1430 lines
		
	
	
		
			56 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
			
		
		
	
	
			1430 lines
		
	
	
		
			56 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
/*
 | 
						|
 * Inline Form Validation Engine 2.2, jQuery plugin
 | 
						|
 *
 | 
						|
 * Copyright(c) 2010, Cedric Dugas
 | 
						|
 * http://www.position-absolute.com
 | 
						|
 *
 | 
						|
 * 2.0 Rewrite by Olivier Refalo
 | 
						|
 * http://www.crionics.com
 | 
						|
 *
 | 
						|
 * Form validation engine allowing custom regex rules to be added.
 | 
						|
 * Licensed under the MIT License
 | 
						|
 */
 | 
						|
(function($) {
 | 
						|
 | 
						|
    var methods = {
 | 
						|
 | 
						|
        /**
 | 
						|
         * Kind of the constructor, called before any action
 | 
						|
         * @param {Map} user options
 | 
						|
         */
 | 
						|
        init: function(options) {
 | 
						|
            var form = this;
 | 
						|
            if (!form.data('jqv') || form.data('jqv') == null ) {
 | 
						|
                methods._saveOptions(form, options);
 | 
						|
 | 
						|
                // bind all formError elements to close on click
 | 
						|
                $(".formError").live("click", function() {
 | 
						|
                    $(this).fadeOut(150, function() {
 | 
						|
 | 
						|
                        // remove prompt once invisible
 | 
						|
                        $(this).remove();
 | 
						|
                    });
 | 
						|
                });
 | 
						|
            }
 | 
						|
        },
 | 
						|
        /**
 | 
						|
         * Attachs jQuery.validationEngine to form.submit and field.blur events
 | 
						|
         * Takes an optional params: a list of options
 | 
						|
         * ie. jQuery("#formID1").validationEngine('attach', {promptPosition : "centerRight"});
 | 
						|
         */
 | 
						|
        attach: function(userOptions) {
 | 
						|
			
 | 
						|
            var form = this;
 | 
						|
            var options;
 | 
						|
 | 
						|
            if(userOptions)
 | 
						|
                options = methods._saveOptions(form, userOptions);
 | 
						|
            else
 | 
						|
                options = form.data('jqv');
 | 
						|
 | 
						|
			var validateAttribute = (form.find("[data-validation-engine*=validate]")) ? "data-validation-engine" : "class";
 | 
						|
			
 | 
						|
            if (!options.binded) {
 | 
						|
					if (options.bindMethod == "bind"){
 | 
						|
						
 | 
						|
						// bind fields
 | 
						|
                        form.find("[class*=validate]").not("[type=checkbox]").not("[type=radio]").not(".datepicker").bind(options.validationEventTrigger, methods._onFieldEvent);
 | 
						|
                        form.find("[class*=validate][type=checkbox],[class*=validate][type=radio]").bind("click", methods._onFieldEvent);
 | 
						|
						
 | 
						|
						form.find("[class*=validate][class*=datepicker]").bind(options.validationEventTrigger,{"delay": 300}, methods._onFieldEvent);
 | 
						|
 | 
						|
                        // bind form.submit
 | 
						|
                        //form.bind("submit", methods._onSubmitEvent);
 | 
						|
					} else if (options.bindMethod == "live") {
 | 
						|
                        // bind fields with LIVE (for persistant state)
 | 
						|
                        form.find("[class*=validate]").not("[type=checkbox]").not(".datepicker").live(options.validationEventTrigger, methods._onFieldEvent);
 | 
						|
                        form.find("[class*=validate][type=checkbox]").live("click", methods._onFieldEvent);
 | 
						|
 | 
						|
						form.find("[class*=validate][class*=datepicker]").live(options.validationEventTrigger,{"delay": 300}, methods._onFieldEvent);
 | 
						|
 | 
						|
                        // bind form.submit
 | 
						|
                        //form.live("submit", methods._onSubmitEvent);
 | 
						|
					}
 | 
						|
 | 
						|
                options.binded = true;
 | 
						|
            }
 | 
						|
			return this;
 | 
						|
        },
 | 
						|
        /**
 | 
						|
         * Unregisters any bindings that may point to jQuery.validaitonEngine
 | 
						|
         */
 | 
						|
        detach: function() {
 | 
						|
            var form = this;
 | 
						|
            var options = form.data('jqv');
 | 
						|
            if (options.binded) {
 | 
						|
 | 
						|
                // unbind fields
 | 
						|
                form.find("[class*=validate]").not("[type=checkbox]").unbind(options.validationEventTrigger, methods._onFieldEvent);
 | 
						|
                form.find("[class*=validate][type=checkbox],[class*=validate][type=radio]").unbind("click", methods._onFieldEvent);
 | 
						|
 | 
						|
                // unbind form.submit
 | 
						|
                form.unbind("submit", methods.onAjaxFormComplete);
 | 
						|
                
 | 
						|
               
 | 
						|
                // unbind live fields (kill)
 | 
						|
                form.find("[class*=validate]").not("[type=checkbox]").die(options.validationEventTrigger, methods._onFieldEvent);
 | 
						|
                form.find("[class*=validate][type=checkbox]").die("click", methods._onFieldEvent);
 | 
						|
                // unbind form.submit
 | 
						|
 | 
						|
				
 | 
						|
 | 
						|
 | 
						|
                form.die("submit", methods.onAjaxFormComplete);
 | 
						|
                
 | 
						|
                form.removeData('jqv');
 | 
						|
            }
 | 
						|
        },
 | 
						|
        /**
 | 
						|
         * Validates the form fields, shows prompts accordingly.
 | 
						|
         * Note: There is no ajax form validation with this method, only field ajax validation are evaluated
 | 
						|
         *
 | 
						|
         * @return true if the form validates, false if it fails
 | 
						|
         */
 | 
						|
        validate: function() {
 | 
						|
            return methods._validateFields(this);
 | 
						|
        },
 | 
						|
        /**
 | 
						|
         * Validates one field, shows prompt accordingly.
 | 
						|
         * Note: There is no ajax form validation with this method, only field ajax validation are evaluated
 | 
						|
         *
 | 
						|
         * @return true if the form validates, false if it fails
 | 
						|
         */
 | 
						|
        validateField: function(el) {
 | 
						|
            var options = $(this).data('jqv');
 | 
						|
            return methods._validateField($(el), options);
 | 
						|
        },
 | 
						|
        /**
 | 
						|
         * Validates the form fields, shows prompts accordingly.
 | 
						|
         * Note: this methods performs fields and form ajax validations(if setup)
 | 
						|
         *
 | 
						|
         * @return true if the form validates, false if it fails, undefined if ajax is used for form validation
 | 
						|
         */
 | 
						|
        validateform: function() {
 | 
						|
            return methods._onSubmitEvent.call(this);
 | 
						|
        },
 | 
						|
		/**
 | 
						|
         *  Redraw prompts position, useful when you change the DOM state when validating
 | 
						|
         */
 | 
						|
        updatePromptsPosition: function() {
 | 
						|
			var form = this.closest('form');
 | 
						|
            var options = form.data('jqv');
 | 
						|
            // No option, take default one
 | 
						|
			form.find('[class*=validate]').not(':hidden').not(":disabled").each(function(){
 | 
						|
				var field = $(this);
 | 
						|
 | 
						|
				var prompt = methods._getPrompt(field);
 | 
						|
				var promptText = $(prompt).find(".formErrorContent").html();
 | 
						|
 | 
						|
				if(prompt) methods._updatePrompt(field, $(prompt), promptText, undefined, false, options);
 | 
						|
			})
 | 
						|
        },
 | 
						|
        /**
 | 
						|
         * Displays a prompt on a element.
 | 
						|
         * Note that the element needs an id!
 | 
						|
         *
 | 
						|
         * @param {String} promptText html text to display type
 | 
						|
         * @param {String} type the type of bubble: 'pass' (green), 'load' (black) anything else (red)
 | 
						|
         * @param {String} possible values topLeft, topRight, bottomLeft, centerRight, bottomRight
 | 
						|
         */
 | 
						|
        showPrompt: function(promptText, type, promptPosition, showArrow) {
 | 
						|
 | 
						|
            var form = this.closest('form');
 | 
						|
            var options = form.data('jqv');
 | 
						|
            // No option, take default one
 | 
						|
			if(!options) options = methods._saveOptions(this, options);
 | 
						|
            if(promptPosition)
 | 
						|
                options.promptPosition=promptPosition;
 | 
						|
            options.showArrow = showArrow==true;
 | 
						|
 | 
						|
            methods._showPrompt(this, promptText, type, false, options);
 | 
						|
        },
 | 
						|
        /**
 | 
						|
         * Closes all error prompts on the page
 | 
						|
         */
 | 
						|
        hidePrompt: function() {
 | 
						|
        	var promptClass =  "."+ methods._getClassName($(this).attr("id")) + "formError";
 | 
						|
            $(promptClass).fadeTo("fast", 0.3, function() {
 | 
						|
                $(this).remove();
 | 
						|
            });
 | 
						|
        },
 | 
						|
        /**
 | 
						|
         * Closes form error prompts, CAN be invidual
 | 
						|
         */
 | 
						|
        hide: function() {
 | 
						|
			var closingtag;
 | 
						|
        	if($(this).is("form")){
 | 
						|
        		closingtag = "parentForm"+$(this).attr('id');
 | 
						|
        	}else{
 | 
						|
        		closingtag = $(this).attr('id') +"formError";
 | 
						|
        	}
 | 
						|
            $('.'+closingtag).fadeTo("fast", 0.3, function() {
 | 
						|
                $(this).remove();
 | 
						|
            });
 | 
						|
        },
 | 
						|
        /**
 | 
						|
         * Closes all error prompts on the page
 | 
						|
         */
 | 
						|
        hideAll: function() {
 | 
						|
            $('.formError').fadeTo("fast", 0.3, function() {
 | 
						|
                $(this).remove();
 | 
						|
            });
 | 
						|
        },
 | 
						|
        /**
 | 
						|
         * Typically called when user exists a field using tab or a mouse click, triggers a field
 | 
						|
         * validation
 | 
						|
         */
 | 
						|
        _onFieldEvent: function(event) {
 | 
						|
            var field = $(this);
 | 
						|
            var form = field.closest('form');
 | 
						|
            var options = form.data('jqv');
 | 
						|
            // validate the current field
 | 
						|
			window.setTimeout(function() {
 | 
						|
			    methods._validateField(field, options);
 | 
						|
			}, (event.data) ? event.data.delay : 0);
 | 
						|
            
 | 
						|
        },
 | 
						|
        /**
 | 
						|
         * Called when the form is submited, shows prompts accordingly
 | 
						|
         *
 | 
						|
         * @param {jqObject}
 | 
						|
         *            form
 | 
						|
         * @return false if form submission needs to be cancelled
 | 
						|
         */
 | 
						|
        _onSubmitEvent: function() {
 | 
						|
            var form = $(this);
 | 
						|
 			var options = form.data('jqv');
 | 
						|
   
 | 
						|
			// validate each field (- skip field ajax validation, no necessary since we will perform an ajax form validation)
 | 
						|
            var r=methods._validateFields(form, true);
 | 
						|
		
 | 
						|
            if (r && options.ajaxFormValidation) {
 | 
						|
                methods._validateFormWithAjax(form, options);
 | 
						|
                return false;
 | 
						|
            }
 | 
						|
 | 
						|
            if(options.onValidationComplete) {
 | 
						|
                options.onValidationComplete(form, r);
 | 
						|
                return false;
 | 
						|
            }
 | 
						|
            return r;
 | 
						|
        },
 | 
						|
 | 
						|
        /**
 | 
						|
         * Return true if the ajax field validations passed so far
 | 
						|
         * @param {Object} options
 | 
						|
         * @return true, is all ajax validation passed so far (remember ajax is async)
 | 
						|
         */
 | 
						|
        _checkAjaxStatus: function(options) {
 | 
						|
            var status = true;
 | 
						|
            $.each(options.ajaxValidCache, function(key, value) {
 | 
						|
                if (!value) {
 | 
						|
                    status = false;
 | 
						|
                    // break the each
 | 
						|
                    return false;
 | 
						|
                }
 | 
						|
            });
 | 
						|
            return status;
 | 
						|
        },
 | 
						|
        /**
 | 
						|
         * Validates form fields, shows prompts accordingly
 | 
						|
         *
 | 
						|
         * @param {jqObject}
 | 
						|
         *            form
 | 
						|
         * @param {skipAjaxFieldValidation}
 | 
						|
         *            boolean - when set to true, ajax field validation is skipped, typically used when the submit button is clicked
 | 
						|
         *
 | 
						|
         * @return true if form is valid, false if not, undefined if ajax form validation is done
 | 
						|
         */
 | 
						|
        _validateFields: function(form, skipAjaxValidation) {
 | 
						|
            var options = form.data('jqv');
 | 
						|
 | 
						|
            // this variable is set to true if an error is found
 | 
						|
            var errorFound = false;
 | 
						|
			
 | 
						|
			// Trigger hook, start validation
 | 
						|
			form.trigger("jqv.form.validating");
 | 
						|
            // first, evaluate status of non ajax fields
 | 
						|
            form.find('[class*=validate]').not(':hidden').not(":disabled").each( function() {
 | 
						|
                var field = $(this);
 | 
						|
                errorFound |= methods._validateField(field, options, skipAjaxValidation);
 | 
						|
            });
 | 
						|
            // second, check to see if all ajax calls completed ok
 | 
						|
            // errorFound |= !methods._checkAjaxStatus(options);
 | 
						|
			
 | 
						|
            // thrird, check status and scroll the container accordingly
 | 
						|
			form.trigger("jqv.form.result", [errorFound]);
 | 
						|
			
 | 
						|
            if (errorFound) {
 | 
						|
				
 | 
						|
                if (options.scroll) {
 | 
						|
 | 
						|
                    // get the position of the first error, there should be at least one, no need to check this
 | 
						|
                    //var destination = form.find(".formError:not('.greenPopup'):first").offset().top;
 | 
						|
 | 
						|
                    // look for the visually top prompt
 | 
						|
                    var destination = Number.MAX_VALUE;
 | 
						|
                    var fixleft = 0;
 | 
						|
                    var lst = $(".formError:not('.greenPopup')");
 | 
						|
 | 
						|
                    for (var i = 0; i < lst.length; i++) {
 | 
						|
                        var d = $(lst[i]).offset().top;
 | 
						|
                        if (d < destination){
 | 
						|
                            destination = d;
 | 
						|
                            fixleft = $(lst[i]).offset().left;
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
 | 
						|
                    if (!options.isOverflown)
 | 
						|
                        $("html:not(:animated),body:not(:animated)").animate({
 | 
						|
                            scrollTop: destination,
 | 
						|
                            scrollLeft: fixleft
 | 
						|
                        }, 1100);
 | 
						|
                    else {
 | 
						|
                        var overflowDIV = $(options.overflownDIV);
 | 
						|
                        var scrollContainerScroll = overflowDIV.scrollTop();
 | 
						|
                        var scrollContainerPos = -parseInt(overflowDIV.offset().top);
 | 
						|
 | 
						|
                        destination += scrollContainerScroll + scrollContainerPos - 5;
 | 
						|
                        var scrollContainer = $(options.overflownDIV + ":not(:animated)");
 | 
						|
 | 
						|
                        scrollContainer.animate({
 | 
						|
                            scrollTop: destination
 | 
						|
                        }, 1100);
 | 
						|
 | 
						|
                        $("html:not(:animated),body:not(:animated)").animate({
 | 
						|
                            scrollTop: overflowDIV.offset().top,
 | 
						|
                            scrollLeft: fixleft
 | 
						|
                        }, 1100);
 | 
						|
                    }
 | 
						|
                }
 | 
						|
                return false;
 | 
						|
            }
 | 
						|
            return true;
 | 
						|
        },
 | 
						|
        /**
 | 
						|
         * This method is called to perform an ajax form validation.
 | 
						|
         * During this process all the (field, value) pairs are sent to the server which returns a list of invalid fields or true
 | 
						|
         *
 | 
						|
         * @param {jqObject} form
 | 
						|
         * @param {Map} options
 | 
						|
         */
 | 
						|
        _validateFormWithAjax: function(form, options) {
 | 
						|
 | 
						|
            var data = form.serialize();
 | 
						|
			var url = (options.ajaxFormValidationURL) ? options.ajaxFormValidationURL : form.attr("action");
 | 
						|
            $.ajax({
 | 
						|
                type: "GET",
 | 
						|
                url: url,
 | 
						|
                cache: false,
 | 
						|
                dataType: "json",
 | 
						|
                data: data,
 | 
						|
                form: form,
 | 
						|
                methods: methods,
 | 
						|
                options: options,
 | 
						|
                beforeSend: function() {
 | 
						|
                    return options.onBeforeAjaxFormValidation(form, options);
 | 
						|
                },
 | 
						|
                error: function(data, transport) {
 | 
						|
                    methods._ajaxError(data, transport);
 | 
						|
                },
 | 
						|
                success: function(json) {
 | 
						|
 | 
						|
                    if (json !== true) {
 | 
						|
 | 
						|
                        // getting to this case doesn't necessary means that the form is invalid
 | 
						|
                        // the server may return green or closing prompt actions
 | 
						|
                        // this flag helps figuring it out
 | 
						|
                        var errorInForm=false;
 | 
						|
                        for (var i = 0; i < json.length; i++) {
 | 
						|
                            var value = json[i];
 | 
						|
						
 | 
						|
                            var errorFieldId = value[0];
 | 
						|
                            var errorField = $($("#" + errorFieldId)[0]);
 | 
						|
							
 | 
						|
                            // make sure we found the element
 | 
						|
                            if (errorField.length == 1) {
 | 
						|
								
 | 
						|
                                // promptText or selector
 | 
						|
                                var msg = value[2];
 | 
						|
								// if the field is valid
 | 
						|
                                if (value[1] == true) {
 | 
						|
 | 
						|
                                    if (msg == ""  || !msg){
 | 
						|
                                        // if for some reason, status==true and error="", just close the prompt
 | 
						|
                                        methods._closePrompt(errorField);
 | 
						|
                                    } else {
 | 
						|
                                        // the field is valid, but we are displaying a green prompt
 | 
						|
                                        if (options.allrules[msg]) {
 | 
						|
                                            var txt = options.allrules[msg].alertTextOk;
 | 
						|
                                            if (txt)
 | 
						|
                                                msg = txt;
 | 
						|
                                        }
 | 
						|
                                        methods._showPrompt(errorField, msg, "pass", false, options, true);
 | 
						|
                                    }
 | 
						|
 | 
						|
                                } else {
 | 
						|
                                    // the field is invalid, show the red error prompt
 | 
						|
                                    errorInForm|=true;
 | 
						|
                                    if (options.allrules[msg]) {
 | 
						|
                                        var txt = options.allrules[msg].alertText;
 | 
						|
                                        if (txt)
 | 
						|
                                            msg = txt;
 | 
						|
                                    }
 | 
						|
                                    methods._showPrompt(errorField, msg, "", false, options, true);
 | 
						|
                                }
 | 
						|
                            }
 | 
						|
                        }
 | 
						|
                        options.onAjaxFormComplete(!errorInForm, form, json, options);
 | 
						|
                    } else
 | 
						|
                        options.onAjaxFormComplete(true, form, "", options);
 | 
						|
                }
 | 
						|
            });
 | 
						|
 | 
						|
        },
 | 
						|
        /**
 | 
						|
         * Validates field, shows prompts accordingly
 | 
						|
         *
 | 
						|
         * @param {jqObject}
 | 
						|
         *            field
 | 
						|
         * @param {Array[String]}
 | 
						|
         *            field's validation rules
 | 
						|
         * @param {Map}
 | 
						|
         *            user options
 | 
						|
         * @return true if field is valid
 | 
						|
         */
 | 
						|
        _validateField: function(field, options, skipAjaxValidation) {
 | 
						|
            if (!field.attr("id"))
 | 
						|
                $.error("jQueryValidate: an ID attribute is required for this field: " + field.attr("name") + " class:" +
 | 
						|
                field.attr("class"));
 | 
						|
 | 
						|
            var rulesParsing = field.attr('class');
 | 
						|
            var getRules = /validate\[(.*)\]/.exec(rulesParsing);
 | 
						|
            if (!getRules)
 | 
						|
                return false;
 | 
						|
            var str = getRules[1];
 | 
						|
            var rules = str.split(/\[|,|\]/);
 | 
						|
 | 
						|
            // true if we ran the ajax validation, tells the logic to stop messing with prompts
 | 
						|
            var isAjaxValidator = false;
 | 
						|
            var fieldName = field.attr("name");
 | 
						|
            var promptText = "";
 | 
						|
			var required = false;
 | 
						|
            options.isError = false;
 | 
						|
            options.showArrow = true;
 | 
						|
 | 
						|
            for (var i = 0; i < rules.length; i++) {
 | 
						|
 | 
						|
                var errorMsg = undefined;
 | 
						|
                switch (rules[i]) {
 | 
						|
 | 
						|
                    case "required":
 | 
						|
                        required = true;
 | 
						|
                        errorMsg = methods._required(field, rules, i, options);
 | 
						|
                        break;
 | 
						|
                    case "custom":
 | 
						|
                        errorMsg = methods._customRegex(field, rules, i, options);
 | 
						|
                        break;
 | 
						|
					case "groupRequired":
 | 
						|
						// Check is its the first of group, if not, reload validation with first field
 | 
						|
						// AND continue normal validation on present field
 | 
						|
						var classGroup = "[class*=" +rules[i + 1] +"]";	
 | 
						|
						var firstOfGroup = field.closest("form").find(classGroup).eq(0);
 | 
						|
						if(firstOfGroup[0] != field[0]){
 | 
						|
							methods._validateField(firstOfGroup, options, skipAjaxValidation)
 | 
						|
							options.showArrow = true;
 | 
						|
							continue;
 | 
						|
						};
 | 
						|
                        errorMsg = methods._groupRequired(field, rules, i, options);
 | 
						|
						if(errorMsg) required = true;
 | 
						|
						options.showArrow = false;
 | 
						|
                        break;
 | 
						|
                    case "ajax":
 | 
						|
                        // ajax has its own prompts handling technique
 | 
						|
						if(!skipAjaxValidation){
 | 
						|
							methods._ajax(field, rules, i, options);
 | 
						|
	                        isAjaxValidator = true;
 | 
						|
						}
 | 
						|
                        break;
 | 
						|
                    case "minSize":
 | 
						|
                        errorMsg = methods._minSize(field, rules, i, options);
 | 
						|
                        break;
 | 
						|
                    case "maxSize":
 | 
						|
                        errorMsg = methods._maxSize(field, rules, i, options);
 | 
						|
                        break;
 | 
						|
                    case "min":
 | 
						|
                        errorMsg = methods._min(field, rules, i, options);
 | 
						|
                        break;
 | 
						|
                    case "max":
 | 
						|
                        errorMsg = methods._max(field, rules, i, options);
 | 
						|
                        break;
 | 
						|
                    case "past":
 | 
						|
                        errorMsg = methods._past(field, rules, i, options);
 | 
						|
                        break;
 | 
						|
                    case "future":
 | 
						|
                        errorMsg = methods._future(field, rules, i, options);
 | 
						|
                        break;
 | 
						|
                    case "dateRange":
 | 
						|
                        var classGroup = "[class*=" + rules[i + 1] + "]";
 | 
						|
                        var firstOfGroup = field.closest("form").find(classGroup).eq(0);
 | 
						|
                        var secondOfGroup = field.closest("form").find(classGroup).eq(1);
 | 
						|
                        /*
 | 
						|
                        if (firstOfGroup[0] != field[0]) {
 | 
						|
                            methods._validateField(firstOfGroup, options, skipAjaxValidation)
 | 
						|
                            options.showArrow = true;
 | 
						|
                            continue;
 | 
						|
                        };
 | 
						|
                        */
 | 
						|
                        //if one entry out of the pair has value then proceed to run through validation
 | 
						|
                        if (firstOfGroup[0].value || secondOfGroup[0].value) {
 | 
						|
                            errorMsg = methods._dateRange(firstOfGroup, secondOfGroup, rules, i, options);
 | 
						|
                        }
 | 
						|
                        if (errorMsg) required = true;
 | 
						|
                        options.showArrow = false;
 | 
						|
                        break;
 | 
						|
 | 
						|
                    case "dateTimeRange":
 | 
						|
                        var classGroup = "[class*=" + rules[i + 1] + "]";
 | 
						|
                        var firstOfGroup = field.closest("form").find(classGroup).eq(0);
 | 
						|
                        var secondOfGroup = field.closest("form").find(classGroup).eq(1);
 | 
						|
                        /*
 | 
						|
                        if (firstOfGroup[0] != field[0]) {
 | 
						|
                            methods._validateField(firstOfGroup, options, skipAjaxValidation)
 | 
						|
                            options.showArrow = true;
 | 
						|
                            continue;
 | 
						|
                        };
 | 
						|
                        */
 | 
						|
                        //if one entry out of the pair has value then proceed to run through validation
 | 
						|
                        if (firstOfGroup[0].value || secondOfGroup[0].value) {
 | 
						|
                            errorMsg = methods._dateTimeRange(firstOfGroup, secondOfGroup, rules, i, options);
 | 
						|
                        }
 | 
						|
                        if (errorMsg) required = true;
 | 
						|
                        options.showArrow = false;
 | 
						|
                        break;
 | 
						|
                    case "maxCheckbox":
 | 
						|
                        errorMsg = methods._maxCheckbox(field, rules, i, options);
 | 
						|
                        field = $($("input[name='" + fieldName + "']"));
 | 
						|
                        break;
 | 
						|
                    case "minCheckbox":
 | 
						|
                        errorMsg = methods._minCheckbox(field, rules, i, options);
 | 
						|
                        field = $($("input[name='" + fieldName + "']"));
 | 
						|
                        break;
 | 
						|
                    case "equals":
 | 
						|
                        errorMsg = methods._equals(field, rules, i, options);
 | 
						|
                        break;
 | 
						|
                    case "funcCall":
 | 
						|
                        errorMsg = methods._funcCall(field, rules, i, options);
 | 
						|
                        break;
 | 
						|
 | 
						|
                    default:
 | 
						|
                    //$.error("jQueryValidator rule not found"+rules[i]);
 | 
						|
                }
 | 
						|
                if (errorMsg !== undefined) {
 | 
						|
                    promptText += errorMsg + "<br/>";
 | 
						|
                    options.isError = true;
 | 
						|
					
 | 
						|
                }
 | 
						|
 | 
						|
            }
 | 
						|
            // If the rules required is not added, an empty field is not validated
 | 
						|
            if(!required){
 | 
						|
            	if(field.val() == "") options.isError = false;
 | 
						|
            }			
 | 
						|
			
 | 
						|
            // Hack for radio/checkbox group button, the validation go into the
 | 
						|
            // first radio/checkbox of the group
 | 
						|
            var fieldType = field.attr("type");
 | 
						|
 | 
						|
            if ((fieldType == "radio" || fieldType == "checkbox") && $("input[name='" + fieldName + "']").size() > 1) {
 | 
						|
                field = $($("input[name='" + fieldName + "'][type!=hidden]:first"));
 | 
						|
                options.showArrow = false;
 | 
						|
            }
 | 
						|
            if (fieldType == "text" && $("input[name='" + fieldName + "']").size() > 1) {
 | 
						|
                field = $($("input[name='" + fieldName + "'][type!=hidden]:first"));
 | 
						|
                options.showArrow = false;
 | 
						|
            }
 | 
						|
 | 
						|
            if (options.isError){
 | 
						|
				
 | 
						|
                methods._showPrompt(field, promptText, "", false, options);
 | 
						|
            }else{
 | 
						|
				if (!isAjaxValidator) methods._closePrompt(field);
 | 
						|
			}
 | 
						|
			field.trigger("jqv.field.result", [field, options.isError, promptText]);
 | 
						|
            return options.isError;
 | 
						|
        },
 | 
						|
        /**
 | 
						|
         * Required validation
 | 
						|
         *
 | 
						|
         * @param {jqObject} field
 | 
						|
         * @param {Array[String]} rules
 | 
						|
         * @param {int} i rules index
 | 
						|
         * @param {Map}
 | 
						|
         *            user options
 | 
						|
         * @return an error string if validation failed
 | 
						|
         */
 | 
						|
        _required: function(field, rules, i, options) {
 | 
						|
            switch (field.attr("type")) {
 | 
						|
                case "text":
 | 
						|
                case "password":
 | 
						|
                case "textarea":
 | 
						|
                case "file":
 | 
						|
                default:
 | 
						|
                    if (!field.val())
 | 
						|
                        return options.allrules[rules[i]].alertText;
 | 
						|
                    break;
 | 
						|
                case "radio":
 | 
						|
                case "checkbox":
 | 
						|
                    var name = field.attr("name");
 | 
						|
                    if ($("input[name='" + name + "']:checked").size() == 0) {
 | 
						|
                        if ($("input[name='" + name + "']").size() == 1)
 | 
						|
                            return options.allrules[rules[i]].alertTextCheckboxe;
 | 
						|
                        else
 | 
						|
                            return options.allrules[rules[i]].alertTextCheckboxMultiple;
 | 
						|
                    }
 | 
						|
                    break;
 | 
						|
                // required for <select>
 | 
						|
                case "select-one":
 | 
						|
                    // added by paul@kinetek.net for select boxes, Thank you
 | 
						|
                    if (!field.val())
 | 
						|
                        return options.allrules[rules[i]].alertText;
 | 
						|
                    break;
 | 
						|
                case "select-multiple":
 | 
						|
                    // added by paul@kinetek.net for select boxes, Thank you
 | 
						|
                    if (!field.find("option:selected").val())
 | 
						|
                        return options.allrules[rules[i]].alertText;
 | 
						|
                    break;
 | 
						|
            }
 | 
						|
        },
 | 
						|
		/**
 | 
						|
         * Validate that 1 from the group field is required
 | 
						|
         *
 | 
						|
         * @param {jqObject} field
 | 
						|
         * @param {Array[String]} rules
 | 
						|
         * @param {int} i rules index
 | 
						|
         * @param {Map}
 | 
						|
         *            user options
 | 
						|
         * @return an error string if validation failed
 | 
						|
         */
 | 
						|
        _groupRequired: function(field, rules, i, options) {
 | 
						|
            var classGroup = "[class*=" +rules[i + 1] +"]";
 | 
						|
			var isValid = false;
 | 
						|
			// Check all fields from the group
 | 
						|
			field.closest("form").find(classGroup).each(function(){
 | 
						|
				if(!methods._required($(this), rules, i, options)){
 | 
						|
					isValid = true;
 | 
						|
					return false;
 | 
						|
				}
 | 
						|
			})
 | 
						|
			
 | 
						|
			if(!isValid) return options.allrules[rules[i]].alertText;
 | 
						|
        },
 | 
						|
        /**
 | 
						|
         * Validate Regex rules
 | 
						|
         *
 | 
						|
         * @param {jqObject} field
 | 
						|
         * @param {Array[String]} rules
 | 
						|
         * @param {int} i rules index
 | 
						|
         * @param {Map}
 | 
						|
         *            user options
 | 
						|
         * @return an error string if validation failed
 | 
						|
         */
 | 
						|
        _customRegex: function(field, rules, i, options) {
 | 
						|
            var customRule = rules[i + 1];
 | 
						|
			var rule = options.allrules[customRule];
 | 
						|
			if(!rule) {
 | 
						|
				alert("jqv:custom rule not found "+customRule);
 | 
						|
				return;
 | 
						|
			}
 | 
						|
			
 | 
						|
			var ex=rule.regex;
 | 
						|
			if(!ex) {
 | 
						|
				alert("jqv:custom regex not found "+customRule);
 | 
						|
				return;
 | 
						|
			}
 | 
						|
            var pattern = new RegExp(ex);
 | 
						|
 | 
						|
            if (!pattern.test(field.val()))
 | 
						|
                return options.allrules[customRule].alertText;
 | 
						|
        },
 | 
						|
        /**
 | 
						|
         * Validate custom function outside of the engine scope
 | 
						|
         *
 | 
						|
         * @param {jqObject} field
 | 
						|
         * @param {Array[String]} rules
 | 
						|
         * @param {int} i rules index
 | 
						|
         * @param {Map}
 | 
						|
         *            user options
 | 
						|
         * @return an error string if validation failed
 | 
						|
         */
 | 
						|
        _funcCall: function(field, rules, i, options) {
 | 
						|
            var functionName = rules[i + 1];
 | 
						|
            var fn = window[functionName];
 | 
						|
            if (typeof(fn) == 'function')
 | 
						|
                return fn(field, rules, i, options);
 | 
						|
 | 
						|
        },
 | 
						|
        /**
 | 
						|
         * Field match
 | 
						|
         *
 | 
						|
         * @param {jqObject} field
 | 
						|
         * @param {Array[String]} rules
 | 
						|
         * @param {int} i rules index
 | 
						|
         * @param {Map}
 | 
						|
         *            user options
 | 
						|
         * @return an error string if validation failed
 | 
						|
         */
 | 
						|
        _equals: function(field, rules, i, options) {
 | 
						|
            var equalsField = rules[i + 1];
 | 
						|
 | 
						|
            if (field.val() != $("#" + equalsField).val())
 | 
						|
                return options.allrules.equals.alertText;
 | 
						|
        },
 | 
						|
        /**
 | 
						|
         * Check the maximum size (in characters)
 | 
						|
         *
 | 
						|
         * @param {jqObject} field
 | 
						|
         * @param {Array[String]} rules
 | 
						|
         * @param {int} i rules index
 | 
						|
         * @param {Map}
 | 
						|
         *            user options
 | 
						|
         * @return an error string if validation failed
 | 
						|
         */
 | 
						|
        _maxSize: function(field, rules, i, options) {
 | 
						|
            var max = rules[i + 1];
 | 
						|
            var len = field.val().length;
 | 
						|
 | 
						|
            if (len > max) {
 | 
						|
                var rule = options.allrules.maxSize;
 | 
						|
                return rule.alertText + max + rule.alertText2;
 | 
						|
            }
 | 
						|
        },
 | 
						|
        /**
 | 
						|
         * Check the minimum size (in characters)
 | 
						|
         *
 | 
						|
         * @param {jqObject} field
 | 
						|
         * @param {Array[String]} rules
 | 
						|
         * @param {int} i rules index
 | 
						|
         * @param {Map}
 | 
						|
         *            user options
 | 
						|
         * @return an error string if validation failed
 | 
						|
         */
 | 
						|
        _minSize: function(field, rules, i, options) {
 | 
						|
            var min = rules[i + 1];
 | 
						|
            var len = field.val().length;
 | 
						|
 | 
						|
            if (len < min) {
 | 
						|
                var rule = options.allrules.minSize;
 | 
						|
                return rule.alertText + min + rule.alertText2;
 | 
						|
            }
 | 
						|
        },
 | 
						|
        /**
 | 
						|
         * Check number minimum value
 | 
						|
         *
 | 
						|
         * @param {jqObject} field
 | 
						|
         * @param {Array[String]} rules
 | 
						|
         * @param {int} i rules index
 | 
						|
         * @param {Map}
 | 
						|
         *            user options
 | 
						|
         * @return an error string if validation failed
 | 
						|
         */
 | 
						|
        _min: function(field, rules, i, options) {
 | 
						|
            var min = parseFloat(rules[i + 1]);
 | 
						|
            var len = parseFloat(field.val());
 | 
						|
 | 
						|
            if (len < min) {
 | 
						|
                var rule = options.allrules.min;
 | 
						|
                if (rule.alertText2) return rule.alertText + min + rule.alertText2;
 | 
						|
                return rule.alertText + min;
 | 
						|
            }
 | 
						|
        },
 | 
						|
        /**
 | 
						|
         * Check number maximum value
 | 
						|
         *
 | 
						|
         * @param {jqObject} field
 | 
						|
         * @param {Array[String]} rules
 | 
						|
         * @param {int} i rules index
 | 
						|
         * @param {Map}
 | 
						|
         *            user options
 | 
						|
         * @return an error string if validation failed
 | 
						|
         */
 | 
						|
        _max: function(field, rules, i, options) {
 | 
						|
            var max = parseFloat(rules[i + 1]);
 | 
						|
            var len = parseFloat(field.val());
 | 
						|
 | 
						|
            if (len >max ) {
 | 
						|
                var rule = options.allrules.max;
 | 
						|
                if (rule.alertText2) return rule.alertText + max + rule.alertText2;
 | 
						|
                //orefalo: to review, also do the translations
 | 
						|
                return rule.alertText + max;
 | 
						|
            }
 | 
						|
        },
 | 
						|
        /**
 | 
						|
         * Checks date is in the past
 | 
						|
         *
 | 
						|
         * @param {jqObject} field
 | 
						|
         * @param {Array[String]} rules
 | 
						|
         * @param {int} i rules index
 | 
						|
         * @param {Map}
 | 
						|
         *            user options
 | 
						|
         * @return an error string if validation failed
 | 
						|
         */
 | 
						|
        _past: function(field, rules, i, options) {
 | 
						|
 | 
						|
            var p=rules[i + 1];
 | 
						|
            var pdate = (p.toLowerCase() == "now")? new Date():methods._parseDate(p);
 | 
						|
            var vdate = methods._parseDate(field.val());
 | 
						|
 | 
						|
            if (vdate < pdate ) {
 | 
						|
                var rule = options.allrules.past;
 | 
						|
                if (rule.alertText2) return rule.alertText + methods._dateToString(pdate) + rule.alertText2;
 | 
						|
                return rule.alertText + methods._dateToString(pdate);
 | 
						|
            }
 | 
						|
        },
 | 
						|
        /**
 | 
						|
         * Checks date is in the future
 | 
						|
         *
 | 
						|
         * @param {jqObject} field
 | 
						|
         * @param {Array[String]} rules
 | 
						|
         * @param {int} i rules index
 | 
						|
         * @param {Map}
 | 
						|
         *            user options
 | 
						|
         * @return an error string if validation failed
 | 
						|
         */
 | 
						|
        _future: function(field, rules, i, options) {
 | 
						|
 | 
						|
            var p=rules[i + 1];
 | 
						|
            var pdate = (p.toLowerCase() == "now")? new Date():methods._parseDate(p);
 | 
						|
            var vdate = methods._parseDate(field.val());
 | 
						|
 | 
						|
            if (vdate > pdate ) {
 | 
						|
                var rule = options.allrules.future;
 | 
						|
                if (rule.alertText2) return rule.alertText + methods._dateToString(pdate) + rule.alertText2;
 | 
						|
                return rule.alertText + methods._dateToString(pdate);
 | 
						|
            }
 | 
						|
        },
 | 
						|
        /**
 | 
						|
        * Checks if valid date
 | 
						|
        *
 | 
						|
        * @param {string} date string
 | 
						|
        * @return a bool based on determination of valid date
 | 
						|
        */
 | 
						|
        _isDate: function (value) {
 | 
						|
            var dateRegEx = new RegExp(/^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$|^(?:(?:(?:0?[13578]|1[02])(\/|-)31)|(?:(?:0?[1,3-9]|1[0-2])(\/|-)(?:29|30)))(\/|-)(?:[1-9]\d\d\d|\d[1-9]\d\d|\d\d[1-9]\d|\d\d\d[1-9])$|^(?:(?:0?[1-9]|1[0-2])(\/|-)(?:0?[1-9]|1\d|2[0-8]))(\/|-)(?:[1-9]\d\d\d|\d[1-9]\d\d|\d\d[1-9]\d|\d\d\d[1-9])$|^(0?2(\/|-)29)(\/|-)(?:(?:0[48]00|[13579][26]00|[2468][048]00)|(?:\d\d)?(?:0[48]|[2468][048]|[13579][26]))$/);
 | 
						|
            if (dateRegEx.test(value)) {
 | 
						|
                return true;
 | 
						|
            }
 | 
						|
            return false;
 | 
						|
        },
 | 
						|
        /**
 | 
						|
        * Checks if valid date time
 | 
						|
        *
 | 
						|
        * @param {string} date string
 | 
						|
        * @return a bool based on determination of valid date time
 | 
						|
        */
 | 
						|
        _isDateTime: function (value){
 | 
						|
            var dateTimeRegEx = new RegExp(/^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])\s+(1[012]|0?[1-9]){1}:(0?[1-5]|[0-6][0-9]){1}:(0?[0-6]|[0-6][0-9]){1}\s+(am|pm|AM|PM){1}$|^(?:(?:(?:0?[13578]|1[02])(\/|-)31)|(?:(?:0?[1,3-9]|1[0-2])(\/|-)(?:29|30)))(\/|-)(?:[1-9]\d\d\d|\d[1-9]\d\d|\d\d[1-9]\d|\d\d\d[1-9])$|^((1[012]|0?[1-9]){1}\/(0?[1-9]|[12][0-9]|3[01]){1}\/\d{2,4}\s+(1[012]|0?[1-9]){1}:(0?[1-5]|[0-6][0-9]){1}:(0?[0-6]|[0-6][0-9]){1}\s+(am|pm|AM|PM){1})$/);
 | 
						|
            if (dateTimeRegEx.test(value)) {
 | 
						|
                return true;
 | 
						|
            }
 | 
						|
            return false;
 | 
						|
        },
 | 
						|
        //Checks if the start date is before the end date
 | 
						|
        //returns true if end is later than start
 | 
						|
        _dateCompare: function (start, end) {
 | 
						|
            return (new Date(start.toString()) < new Date(end.toString()));
 | 
						|
        },
 | 
						|
        /**
 | 
						|
        * Checks date range
 | 
						|
        *
 | 
						|
        * @param {jqObject} first field name
 | 
						|
        * @param {jqObject} second field name
 | 
						|
        * @return an error string if validation failed
 | 
						|
        */
 | 
						|
        _dateRange: function (first, second, rules, i, options) {
 | 
						|
            //are not both populated
 | 
						|
            if ((!first[0].value && second[0].value) || (first[0].value && !second[0].value)) {
 | 
						|
                return options.allrules[rules[i]].alertText + options.allrules[rules[i]].alertText2;
 | 
						|
            }
 | 
						|
 | 
						|
            //are not both dates
 | 
						|
            if (!methods._isDate(first[0].value) || !methods._isDate(second[0].value)) {
 | 
						|
                return options.allrules[rules[i]].alertText + options.allrules[rules[i]].alertText2;
 | 
						|
            }
 | 
						|
 | 
						|
            //are both dates but range is off
 | 
						|
            if (!methods._dateCompare(first[0].value, second[0].value)) {
 | 
						|
                return options.allrules[rules[i]].alertText + options.allrules[rules[i]].alertText2;
 | 
						|
            }
 | 
						|
        },
 | 
						|
 | 
						|
 | 
						|
        /**
 | 
						|
        * Checks date time range
 | 
						|
        *
 | 
						|
        * @param {jqObject} first field name
 | 
						|
        * @param {jqObject} second field name
 | 
						|
        * @return an error string if validation failed
 | 
						|
        */
 | 
						|
        _dateTimeRange: function (first, second, rules, i, options) {
 | 
						|
            //are not both populated
 | 
						|
            if ((!first[0].value && second[0].value) || (first[0].value && !second[0].value)) {
 | 
						|
                return options.allrules[rules[i]].alertText + options.allrules[rules[i]].alertText2;
 | 
						|
            }
 | 
						|
            //are not both dates
 | 
						|
            if (!methods._isDateTime(first[0].value) || !methods._isDateTime(second[0].value)) {
 | 
						|
                return options.allrules[rules[i]].alertText + options.allrules[rules[i]].alertText2;
 | 
						|
            }
 | 
						|
            //are both dates but range is off
 | 
						|
            if (!methods._dateCompare(first[0].value, second[0].value)) {
 | 
						|
                return options.allrules[rules[i]].alertText + options.allrules[rules[i]].alertText2;
 | 
						|
            }
 | 
						|
        },
 | 
						|
        /**
 | 
						|
         * Max number of checkbox selected
 | 
						|
         *
 | 
						|
         * @param {jqObject} field
 | 
						|
         * @param {Array[String]} rules
 | 
						|
         * @param {int} i rules index
 | 
						|
         * @param {Map}
 | 
						|
         *            user options
 | 
						|
         * @return an error string if validation failed
 | 
						|
         */
 | 
						|
        _maxCheckbox: function(field, rules, i, options) {
 | 
						|
 | 
						|
            var nbCheck = rules[i + 1];
 | 
						|
            var groupname = field.attr("name");
 | 
						|
            var groupSize = $("input[name='" + groupname + "']:checked").size();
 | 
						|
            if (groupSize > nbCheck) {
 | 
						|
                options.showArrow = false;
 | 
						|
                if (options.allrules.maxCheckbox.alertText2) return options.allrules.maxCheckbox.alertText + " " + nbCheck + " " + options.allrules.maxCheckbox.alertText2;
 | 
						|
                return options.allrules.maxCheckbox.alertText;
 | 
						|
            }
 | 
						|
        },
 | 
						|
        /**
 | 
						|
         * Min number of checkbox selected
 | 
						|
         *
 | 
						|
         * @param {jqObject} field
 | 
						|
         * @param {Array[String]} rules
 | 
						|
         * @param {int} i rules index
 | 
						|
         * @param {Map}
 | 
						|
         *            user options
 | 
						|
         * @return an error string if validation failed
 | 
						|
         */
 | 
						|
        _minCheckbox: function(field, rules, i, options) {
 | 
						|
 | 
						|
            var nbCheck = rules[i + 1];
 | 
						|
            var groupname = field.attr("name");
 | 
						|
            var groupSize = $("input[name='" + groupname + "']:checked").size();
 | 
						|
            if (groupSize < nbCheck) {
 | 
						|
                options.showArrow = false;
 | 
						|
                return options.allrules.minCheckbox.alertText + " " + nbCheck + " " +
 | 
						|
                options.allrules.minCheckbox.alertText2;
 | 
						|
            }
 | 
						|
        },
 | 
						|
        /**
 | 
						|
         * Ajax field validation
 | 
						|
         *
 | 
						|
         * @param {jqObject} field
 | 
						|
         * @param {Array[String]} rules
 | 
						|
         * @param {int} i rules index
 | 
						|
         * @param {Map}
 | 
						|
         *            user options
 | 
						|
         * @return nothing! the ajax validator handles the prompts itself
 | 
						|
         */
 | 
						|
        _ajax: function(field, rules, i, options) {
 | 
						|
			
 | 
						|
			
 | 
						|
            var errorSelector = rules[i + 1];
 | 
						|
            var rule = options.allrules[errorSelector];
 | 
						|
            var extraData = rule.extraData;
 | 
						|
            var extraDataDynamic = rule.extraDataDynamic;
 | 
						|
 | 
						|
            if (!extraData)
 | 
						|
                extraData = "";
 | 
						|
 | 
						|
            if (extraDataDynamic) {
 | 
						|
              var tmpData = [];
 | 
						|
              var domIds = String(extraDataDynamic).split(",");
 | 
						|
              for (var i = 0; i < domIds.length; i++) {
 | 
						|
                var id = domIds[i];
 | 
						|
                if ($(id).length) {
 | 
						|
                  var inputValue = field.closest("form").find(id).val();
 | 
						|
                  var keyValue = id.replace('#', '') + '=' + escape(inputValue);
 | 
						|
                  tmpData.push(keyValue);
 | 
						|
                }
 | 
						|
              }
 | 
						|
              extraDataDynamic = tmpData.join("&");
 | 
						|
            } else {
 | 
						|
              extraDataDynamic = "";              
 | 
						|
            }
 | 
						|
                                
 | 
						|
            if (!options.isError) {
 | 
						|
                $.ajax({
 | 
						|
                    type: "GET",
 | 
						|
                    url: rule.url,
 | 
						|
                    cache: false,
 | 
						|
                    dataType: "json",
 | 
						|
                    data: "fieldId=" + field.attr("id") + "&fieldValue=" + field.val() + "&extraData=" + extraData + "&" + extraDataDynamic,
 | 
						|
                    field: field,
 | 
						|
                    rule: rule,
 | 
						|
                    methods: methods,
 | 
						|
                    options: options,
 | 
						|
                    beforeSend: function() {
 | 
						|
                        // build the loading prompt
 | 
						|
                        var loadingText = rule.alertTextLoad;
 | 
						|
                        if (loadingText)
 | 
						|
                            methods._showPrompt(field, loadingText, "load", true, options);
 | 
						|
                    },
 | 
						|
                    error: function(data, transport) {
 | 
						|
                        methods._ajaxError(data, transport);
 | 
						|
                    },
 | 
						|
                    success: function(json) {
 | 
						|
						
 | 
						|
                        // asynchronously called on success, data is the json answer from the server
 | 
						|
                        var errorFieldId = json[0];
 | 
						|
                        var errorField = $($("#" + errorFieldId)[0]);
 | 
						|
                        // make sure we found the element
 | 
						|
                        if (errorField.length == 1) {
 | 
						|
                            var status = json[1];
 | 
						|
							// read the optional msg from the server
 | 
						|
							var msg = json[2];
 | 
						|
                            if (!status) {
 | 
						|
                                // Houston we got a problem - display an red prompt
 | 
						|
                                options.ajaxValidCache[errorFieldId] = false;
 | 
						|
                                options.isError = true;
 | 
						|
 | 
						|
								// resolve the msg prompt
 | 
						|
								if(msg) {
 | 
						|
									if (options.allrules[msg]) {
 | 
						|
                                    	var txt = options.allrules[msg].alertText;
 | 
						|
                                    	if (txt)
 | 
						|
                                    		msg = txt;
 | 
						|
                                    }
 | 
						|
								}
 | 
						|
								else
 | 
						|
                                    msg = rule.alertText;
 | 
						|
                                
 | 
						|
								methods._showPrompt(errorField, msg, "", true, options);
 | 
						|
                            } else {
 | 
						|
                                if (options.ajaxValidCache[errorFieldId] !== undefined)
 | 
						|
                                    options.ajaxValidCache[errorFieldId] = true;
 | 
						|
 | 
						|
                                // resolves the msg prompt
 | 
						|
								if(msg) {
 | 
						|
									if (options.allrules[msg]) {
 | 
						|
							           	var txt = options.allrules[msg].alertTextOk;
 | 
						|
							           	if (txt)
 | 
						|
							           		msg = txt;
 | 
						|
							        }
 | 
						|
								}
 | 
						|
								else
 | 
						|
							       	msg = rule.alertTextOk;                                
 | 
						|
 | 
						|
								// see if we should display a green prompt
 | 
						|
                                if (msg)
 | 
						|
                                    methods._showPrompt(errorField, msg, "pass", true, options);
 | 
						|
                                else
 | 
						|
                                    methods._closePrompt(errorField);
 | 
						|
                            }
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                });
 | 
						|
            }
 | 
						|
        },
 | 
						|
        /**
 | 
						|
         * Common method to handle ajax errors
 | 
						|
         *
 | 
						|
         * @param {Object} data
 | 
						|
         * @param {Object} transport
 | 
						|
         */
 | 
						|
        _ajaxError: function(data, transport) {
 | 
						|
            if(data.status == 0 && transport == null)
 | 
						|
                alert("The page is not served from a server! ajax call failed");
 | 
						|
            else if(typeof console != "undefined")
 | 
						|
                console.log("Ajax error: " + data.status + " " + transport);
 | 
						|
        },
 | 
						|
        /**
 | 
						|
         * date -> string
 | 
						|
         *
 | 
						|
         * @param {Object} date
 | 
						|
         */
 | 
						|
        _dateToString: function(date) {
 | 
						|
 | 
						|
            return date.getFullYear()+"-"+(date.getMonth()+1)+"-"+date.getDate();
 | 
						|
        },
 | 
						|
        /**
 | 
						|
         * Parses an ISO date
 | 
						|
         * @param {String} d
 | 
						|
         */
 | 
						|
        _parseDate: function(d) {
 | 
						|
 | 
						|
            var dateParts = d.split("-");
 | 
						|
            if(dateParts==d)
 | 
						|
                dateParts = d.split("/");
 | 
						|
            return new Date(dateParts[0], (dateParts[1] - 1) ,dateParts[2]);
 | 
						|
        },
 | 
						|
        /**
 | 
						|
         * Builds or updates a prompt with the given information
 | 
						|
         *
 | 
						|
         * @param {jqObject} field
 | 
						|
         * @param {String} promptText html text to display type
 | 
						|
         * @param {String} type the type of bubble: 'pass' (green), 'load' (black) anything else (red)
 | 
						|
         * @param {boolean} ajaxed - use to mark fields than being validated with ajax
 | 
						|
         * @param {Map} options user options
 | 
						|
         */
 | 
						|
        _showPrompt: function(field, promptText, type, ajaxed, options, ajaxform) {
 | 
						|
            var prompt = methods._getPrompt(field);
 | 
						|
			// The ajax submit errors are not see has an error in the form,
 | 
						|
			// When the form errors are returned, the engine see 2 bubbles, but those are ebing closed by the engine at the same time
 | 
						|
			// Because no error was found befor submitting
 | 
						|
			if(ajaxform) prompt = false;
 | 
						|
            if (prompt)
 | 
						|
                methods._updatePrompt(field, prompt, promptText, type, ajaxed, options);
 | 
						|
            else
 | 
						|
                methods._buildPrompt(field, promptText, type, ajaxed, options);
 | 
						|
        },
 | 
						|
        /**
 | 
						|
         * Builds and shades a prompt for the given field.
 | 
						|
         *
 | 
						|
         * @param {jqObject} field
 | 
						|
         * @param {String} promptText html text to display type
 | 
						|
         * @param {String} type the type of bubble: 'pass' (green), 'load' (black) anything else (red)
 | 
						|
         * @param {boolean} ajaxed - use to mark fields than being validated with ajax
 | 
						|
         * @param {Map} options user options
 | 
						|
         */
 | 
						|
        _buildPrompt: function(field, promptText, type, ajaxed, options) {
 | 
						|
 | 
						|
            // create the prompt
 | 
						|
            var prompt = $('<div>');
 | 
						|
            prompt.addClass(methods._getClassName(field.attr("id")) + "formError");
 | 
						|
            // add a class name to identify the parent form of the prompt
 | 
						|
            if(field.is(":input")) prompt.addClass("parentForm"+methods._getClassName(field.parents('form').attr("id")));
 | 
						|
            prompt.addClass("formError");
 | 
						|
 | 
						|
            switch (type) {
 | 
						|
                case "pass":
 | 
						|
                    prompt.addClass("greenPopup");
 | 
						|
                    break;
 | 
						|
                case "load":
 | 
						|
                    prompt.addClass("blackPopup");
 | 
						|
            }
 | 
						|
            if (ajaxed)
 | 
						|
                prompt.addClass("ajaxed");
 | 
						|
 | 
						|
            // create the prompt content
 | 
						|
            var promptContent = $('<div>').addClass("formErrorContent").html(promptText).appendTo(prompt);
 | 
						|
            // create the css arrow pointing at the field
 | 
						|
            // note that there is no triangle on max-checkbox and radio
 | 
						|
            if (options.showArrow) {
 | 
						|
                var arrow = $('<div>').addClass("formErrorArrow");
 | 
						|
 | 
						|
                switch (options.promptPosition) {
 | 
						|
                    case "bottomLeft":
 | 
						|
                    case "bottomRight":
 | 
						|
                        prompt.find(".formErrorContent").before(arrow);
 | 
						|
                        arrow.addClass("formErrorArrowBottom").html('<div class="line1"><!-- --></div><div class="line2"><!-- --></div><div class="line3"><!-- --></div><div class="line4"><!-- --></div><div class="line5"><!-- --></div><div class="line6"><!-- --></div><div class="line7"><!-- --></div><div class="line8"><!-- --></div><div class="line9"><!-- --></div><div class="line10"><!-- --></div>');
 | 
						|
                        break;
 | 
						|
                    case "topLeft":
 | 
						|
                    case "topRight":
 | 
						|
                        arrow.html('<div class="line10"><!-- --></div><div class="line9"><!-- --></div><div class="line8"><!-- --></div><div class="line7"><!-- --></div><div class="line6"><!-- --></div><div class="line5"><!-- --></div><div class="line4"><!-- --></div><div class="line3"><!-- --></div><div class="line2"><!-- --></div><div class="line1"><!-- --></div>');
 | 
						|
                        prompt.append(arrow);
 | 
						|
                        break;
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            //Cedric: Needed if a container is in position:relative
 | 
						|
            // insert prompt in the form or in the overflown container?
 | 
						|
            if (options.isOverflown)
 | 
						|
            	field.before(prompt);
 | 
						|
            else
 | 
						|
               $("body").append(prompt);
 | 
						|
 | 
						|
            var pos = methods._calculatePosition(field, prompt, options);
 | 
						|
            prompt.css({
 | 
						|
                "top": pos.callerTopPosition,
 | 
						|
                "left": pos.callerleftPosition,
 | 
						|
                "marginTop": pos.marginTopSize,
 | 
						|
                "opacity": 0
 | 
						|
            });
 | 
						|
 | 
						|
            return prompt.animate({
 | 
						|
                "opacity": 0.87
 | 
						|
            });
 | 
						|
 | 
						|
        },
 | 
						|
        /**
 | 
						|
         * Updates the prompt text field - the field for which the prompt
 | 
						|
         * @param {jqObject} field
 | 
						|
         * @param {String} promptText html text to display type
 | 
						|
         * @param {String} type the type of bubble: 'pass' (green), 'load' (black) anything else (red)
 | 
						|
         * @param {boolean} ajaxed - use to mark fields than being validated with ajax
 | 
						|
         * @param {Map} options user options
 | 
						|
         */
 | 
						|
        _updatePrompt: function(field, prompt, promptText, type, ajaxed, options) {
 | 
						|
			
 | 
						|
            if (prompt) {
 | 
						|
                if (type == "pass")
 | 
						|
                    prompt.addClass("greenPopup");
 | 
						|
                else
 | 
						|
                    prompt.removeClass("greenPopup");
 | 
						|
 | 
						|
                if (type == "load")
 | 
						|
                    prompt.addClass("blackPopup");
 | 
						|
                else
 | 
						|
                    prompt.removeClass("blackPopup");
 | 
						|
 | 
						|
                if (ajaxed)
 | 
						|
                    prompt.addClass("ajaxed");
 | 
						|
                else
 | 
						|
                    prompt.removeClass("ajaxed");
 | 
						|
 | 
						|
                prompt.find(".formErrorContent").html(promptText);
 | 
						|
 | 
						|
                var pos = methods._calculatePosition(field, prompt, options);
 | 
						|
                prompt.animate({
 | 
						|
                    "top": pos.callerTopPosition,
 | 
						|
                    "left": pos.callerleftPosition,
 | 
						|
                    "marginTop": pos.marginTopSize
 | 
						|
                });
 | 
						|
            }
 | 
						|
        },
 | 
						|
        /**
 | 
						|
         * Closes the prompt associated with the given field
 | 
						|
         *
 | 
						|
         * @param {jqObject}
 | 
						|
         *            field
 | 
						|
         */
 | 
						|
        _closePrompt: function(field) {
 | 
						|
 | 
						|
            var prompt = methods._getPrompt(field);
 | 
						|
            if (prompt)
 | 
						|
                prompt.fadeTo("fast", 0, function() {
 | 
						|
                    prompt.remove();
 | 
						|
                });
 | 
						|
        },
 | 
						|
        closePrompt: function(field) {
 | 
						|
            return methods._closePrompt(field);
 | 
						|
        },
 | 
						|
        /**
 | 
						|
         * Returns the error prompt matching the field if any
 | 
						|
         *
 | 
						|
         * @param {jqObject}
 | 
						|
         *            field
 | 
						|
         * @return undefined or the error prompt (jqObject)
 | 
						|
         */
 | 
						|
  		  _getPrompt: function(field) {
 | 
						|
		    var className = field.attr("id").replace(":","_") + "formError";
 | 
						|
		    var match = $("." + methods._escapeExpression(className))[0];
 | 
						|
		    if (match)
 | 
						|
		      return $(match);
 | 
						|
		  },
 | 
						|
         /**
 | 
						|
         * Returns the escapade classname
 | 
						|
         *
 | 
						|
         * @param {selector}
 | 
						|
         *            className
 | 
						|
         */		
 | 
						|
		  _escapeExpression: function (selector) {
 | 
						|
		    return selector.replace(/([#;&,\.\+\*\~':"\!\^$\[\]\(\)=>\|])/g, "\\$1");
 | 
						|
		  },
 | 
						|
        /**
 | 
						|
        * Calculates prompt position
 | 
						|
        *
 | 
						|
        * @param {jqObject}
 | 
						|
        *            field
 | 
						|
        * @param {jqObject}
 | 
						|
        *            the prompt
 | 
						|
        * @param {Map}
 | 
						|
        *            options
 | 
						|
        * @return positions
 | 
						|
        */
 | 
						|
        _calculatePosition: function (field, promptElmt, options) {
 | 
						|
 | 
						|
            var promptTopPosition, promptleftPosition, marginTopSize;
 | 
						|
            var fieldWidth = field.width();
 | 
						|
            var promptHeight = promptElmt.height();
 | 
						|
 | 
						|
            var overflow = options.isOverflown;
 | 
						|
            if (overflow) {
 | 
						|
                // is the form contained in an overflown container?
 | 
						|
                promptTopPosition = promptleftPosition = 0;
 | 
						|
                // compensation for the arrow
 | 
						|
                marginTopSize = -promptHeight;
 | 
						|
            } else {
 | 
						|
                var offset = field.offset();
 | 
						|
                promptTopPosition = offset.top;
 | 
						|
                promptleftPosition = offset.left;
 | 
						|
                marginTopSize = 0;
 | 
						|
            }
 | 
						|
 | 
						|
            switch (options.promptPosition) {
 | 
						|
 | 
						|
                default:
 | 
						|
                case "topRight":
 | 
						|
                    if (overflow)
 | 
						|
                        // Is the form contained in an overflown container?
 | 
						|
                        promptleftPosition += fieldWidth - 30;
 | 
						|
                    else {
 | 
						|
                        promptleftPosition += fieldWidth - 30;
 | 
						|
                        promptTopPosition += -promptHeight -2;
 | 
						|
                    }
 | 
						|
                    break;
 | 
						|
                case "topLeft":
 | 
						|
                    promptTopPosition += -promptHeight - 10;
 | 
						|
                    break;
 | 
						|
                case "centerRight":
 | 
						|
                    promptleftPosition += fieldWidth + 13;
 | 
						|
                    break;
 | 
						|
                case "bottomLeft":
 | 
						|
                    promptTopPosition = promptTopPosition + field.height() + 15;
 | 
						|
                    break;
 | 
						|
                case "bottomRight":
 | 
						|
                    promptleftPosition += fieldWidth - 30;
 | 
						|
                    promptTopPosition += field.height() + 5;
 | 
						|
            }
 | 
						|
 | 
						|
            return {
 | 
						|
                "callerTopPosition": promptTopPosition + "px",
 | 
						|
                "callerleftPosition": promptleftPosition + "px",
 | 
						|
                "marginTopSize": marginTopSize + "px"
 | 
						|
            };
 | 
						|
        },
 | 
						|
        /**
 | 
						|
         * Saves the user options and variables in the form.data
 | 
						|
         *
 | 
						|
         * @param {jqObject}
 | 
						|
         *            form - the form where the user option should be saved
 | 
						|
         * @param {Map}
 | 
						|
         *            options - the user options
 | 
						|
         * @return the user options (extended from the defaults)
 | 
						|
         */
 | 
						|
        _saveOptions: function(form, options) {
 | 
						|
 | 
						|
            // is there a language localisation ?
 | 
						|
            if ($.validationEngineLanguage)
 | 
						|
                var allRules = $.validationEngineLanguage.allRules;
 | 
						|
            else
 | 
						|
                $.error("jQuery.validationEngine rules are not loaded, plz add localization files to the page");
 | 
						|
			// --- Internals DO NOT TOUCH or OVERLOAD ---
 | 
						|
			// validation rules and i18
 | 
						|
			$.validationEngine.defaults.allrules = allRules;
 | 
						|
			
 | 
						|
            var userOptions = $.extend({},$.validationEngine.defaults, options);
 | 
						|
 | 
						|
            form.data('jqv', userOptions);
 | 
						|
            return userOptions;
 | 
						|
        },
 | 
						|
        
 | 
						|
        /**
 | 
						|
         * Removes forbidden characters from class name
 | 
						|
         * @param {String} className
 | 
						|
         */
 | 
						|
        _getClassName: function(className) {
 | 
						|
        	return className.replace(":","_").replace(".","_");
 | 
						|
        }
 | 
						|
    };
 | 
						|
 | 
						|
    /**
 | 
						|
     * Plugin entry point.
 | 
						|
     * You may pass an action as a parameter or a list of options.
 | 
						|
     * if none, the init and attach methods are being called.
 | 
						|
     * Remember: if you pass options, the attached method is NOT called automatically
 | 
						|
     *
 | 
						|
     * @param {String}
 | 
						|
     *            method (optional) action
 | 
						|
     */
 | 
						|
    $.fn.validationEngine = function(method) {
 | 
						|
 | 
						|
        var form = $(this);
 | 
						|
		  if(!form[0]) return false;  // stop here if the form does not exist
 | 
						|
		  
 | 
						|
        if (typeof(method) == 'string' && method.charAt(0) != '_' && methods[method]) {
 | 
						|
 | 
						|
            // make sure init is called once
 | 
						|
            if(method != "showPrompt" && method != "hidePrompt" && method != "hide" && method != "hideAll") 
 | 
						|
            	methods.init.apply(form);
 | 
						|
 | 
						|
            return methods[method].apply(form, Array.prototype.slice.call(arguments, 1));
 | 
						|
        } else if (typeof method == 'object' || !method) {
 | 
						|
            // default constructor with or without arguments
 | 
						|
			
 | 
						|
			methods.init.apply(form, arguments);
 | 
						|
            return methods.attach.apply(form);
 | 
						|
        } else {
 | 
						|
            $.error('Method ' + method + ' does not exist in jQuery.validationEngine');
 | 
						|
        }
 | 
						|
    };
 | 
						|
	// LEAK GLOBAL OPTIONS
 | 
						|
	$.validationEngine= {defaults:{
 | 
						|
 | 
						|
        // Name of the event triggering field validation
 | 
						|
        validationEventTrigger: "blur",
 | 
						|
        // Automatically scroll viewport to the first error
 | 
						|
        scroll: true,
 | 
						|
        // Opening box position, possible locations are: topLeft,
 | 
						|
        // topRight, bottomLeft, centerRight, bottomRight
 | 
						|
        promptPosition: "topRight",
 | 
						|
        bindMethod:"bind",
 | 
						|
		// internal, automatically set to true when it parse a _ajax rule
 | 
						|
		inlineAjax: false,
 | 
						|
        // if set to true, the form data is sent asynchronously via ajax to the form.action url (get)
 | 
						|
        ajaxFormValidation: false,
 | 
						|
        // Ajax form validation callback method: boolean onComplete(form, status, errors, options)
 | 
						|
        // retuns false if the form.submit event needs to be canceled.
 | 
						|
		ajaxFormValidationURL: false,
 | 
						|
        // The url to send the submit ajax validation (default to action)
 | 
						|
        onAjaxFormComplete: $.noop,
 | 
						|
        // called right before the ajax call, may return false to cancel
 | 
						|
        onBeforeAjaxFormValidation: $.noop,
 | 
						|
        // Stops form from submitting and execute function assiciated with it
 | 
						|
        onValidationComplete: false,
 | 
						|
 | 
						|
        // Used when the form is displayed within a scrolling DIV
 | 
						|
        isOverflown: false,
 | 
						|
        overflownDIV: "",
 | 
						|
 | 
						|
        // true when form and fields are binded
 | 
						|
        binded: false,
 | 
						|
        // set to true, when the prompt arrow needs to be displayed
 | 
						|
        showArrow: true,
 | 
						|
        // did one of the validation fail ? kept global to stop further ajax validations
 | 
						|
        isError: false,
 | 
						|
        // Caches field validation status, typically only bad status are created.
 | 
						|
        // the array is used during ajax form validation to detect issues early and prevent an expensive submit
 | 
						|
        ajaxValidCache: {}
 | 
						|
 | 
						|
    }}
 | 
						|
	
 | 
						|
})(jQuery);
 |