Вход Регистрация
Файл: js/jquery.validationEngine.js
Строк: 2041
<?php
/*
 * Inline Form Validation Engine 2.5.5.1, 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($) {

     
"use strict";

     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 ) {
                 
options methods._saveOptions(formoptions);
                 
// bind all formError elements to close on click
                 
$(".formError").live("click", function() {
                     $(
this).fadeOut(150, function() {
                         
// remove prompt once invisible
                         
$(this).parent('.formErrorOuter').remove();
                         $(
this).remove();
                     });
                 });
             }
             return 
this;
         },
        
/**
        * 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) {

            if(!$(
this).is("form")) {
                
alert("Sorry, jqv.attach() only applies to a form");
                return 
this;
            }
            
            var 
form this;
            var 
options;

            if(
userOptions)
                
options methods._saveOptions(formuserOptions);
            else
                
options form.data('jqv');

            
options.validateAttribute = (form.find("[data-validation-engine*=validate]").length) ? "data-validation-engine" "class";
            if (
options.binded) {

                
// bind fields
                
form.find("["+options.validateAttribute+"*=validate]").not("[type=checkbox]").not("[type=radio]").not(".datepicker").bind(options.validationEventTriggermethods._onFieldEvent);
                
form.find("["+options.validateAttribute+"*=validate][type=checkbox],["+options.validateAttribute+"*=validate][type=radio]").bind("click"methods._onFieldEvent);
                
form.find("["+options.validateAttribute+"*=validate][class*=datepicker]").bind(options.validationEventTrigger,{"delay"300}, methods._onFieldEvent);
            }
            if (
options.autoPositionUpdate) {
                $(
window).bind("resize", {
                    
"noAnimation"true,
                    
"formElem"form
                
}, methods.updatePromptsPosition);
            }
            
// bind form.submit
            
form.bind("submit"methods._onSubmitEvent);
            return 
this;
        },
        
/**
        * Unregisters any bindings that may point to jQuery.validaitonEngine
        */
        
detach: function() {
            
            if(!$(
this).is("form")) {
                
alert("Sorry, jqv.detach() only applies to a form");
                return 
this;
            }

            var 
form this;
            var 
options form.data('jqv');

            
// unbind fields
            
form.find("["+options.validateAttribute+"*=validate]").not("[type=checkbox]").unbind(options.validationEventTriggermethods._onFieldEvent);
            
form.find("["+options.validateAttribute+"*=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("["+options.validateAttribute+"*=validate]").not("[type=checkbox]").die(options.validationEventTriggermethods._onFieldEvent);
            
form.find("["+options.validateAttribute+"*=validate][type=checkbox]").die("click"methods._onFieldEvent);

            
// unbind form.submit
            
form.die("submit"methods.onAjaxFormComplete);
            
form.removeData('jqv');

            if (
options.autoPositionUpdate)
                $(
window).unbind("resize"methods.updatePromptsPosition);

            return 
this;
        },
        
/**
        * Validates either a form or a list of 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() {
            if($(
this).is("form"))
                return 
methods._validateFields(this);
            else {
                
// field validation
                
var form = $(this).closest('form');
                var 
options form.data('jqv');  
                var 
methods._validateField($(this), options);

                if (
options.onSuccess && options.InvalidFields.length == 0)
                    
options.onSuccess();
                else if (
options.onFailure && options.InvalidFields.length 0)
                    
options.onFailure();

                return 
r;
            }
        },
        
/**
        *  Redraw prompts position, useful when you change the DOM state when validating
        */
        
updatePromptsPosition: function(event) {

            if (
event && this == window) {
                var 
form event.data.formElem;
                var 
noAnimation event.data.noAnimation;
            }
            else
                var 
form = $(this.closest('form'));

            var 
options form.data('jqv');
            
// No option, take default one
            
form.find('['+options.validateAttribute+'*=validate]').not(":disabled").each(function(){
                var 
field = $(this);
                var 
prompt methods._getPrompt(field);
                var 
promptText = $(prompt).find(".formErrorContent").html();

                if(
prompt)
                    
methods._updatePrompt(field, $(prompt), promptTextundefinedfalseoptionsnoAnimation);
            });
            return 
this;
        },
        
/**
        * 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(promptTexttypepromptPositionshowArrow) {

            var 
form this.closest('form');
            var 
options form.data('jqv');
            
// No option, take default one
            
if(!options)
                
options methods._saveOptions(thisoptions);
            if(
promptPosition)
                
options.promptPosition=promptPosition;
            
options.showArrow showArrow==true;

            
methods._showPrompt(thispromptTexttypefalseoptions);
            return 
this;
        },
        
/**
        * Closes form error prompts, CAN be invidual
        */
        
hide: function() {
             var 
form = $(this).closest('form');
             if(
form.length == 0)
                return 
this;
             var 
options form.data('jqv');
             var 
closingtag;
             if($(
this).is("form")) {
                 
closingtag "parentForm"+methods._getClassName($(this).attr("id"));
             } else {
                 
closingtag methods._getClassName($(this).attr("id")) +"formError";
             }
             $(
'.'+closingtag).fadeTo(options.fadeDuration0.3, function() {
                 $(
this).parent('.formErrorOuter').remove();
                 $(
this).remove();
             });
             return 
this;
         },
         
/**
         * Closes all error prompts on the page
         */
         
hideAll: function() {

             var 
form this;
             var 
options form.data('jqv');
             var 
duration options options.fadeDuration:0.3;
             $(
'.formError').fadeTo(duration0.3, function() {
                 $(
this).parent('.formErrorOuter').remove();
                 $(
this).remove();
             });
             return 
this;
         },
        
/**
        * 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');
            
options.eventTrigger "field";
            
// validate the current field
            
window.setTimeout(function() {
                
methods._validateField(fieldoptions);
                if (
options.InvalidFields.length == && options.onSuccess) {
                    
options.onSuccess();
                } else if (
options.InvalidFields.length && options.onFailure) {
                    
options.onFailure();
                }
            }, (
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');
            
options.eventTrigger "submit";

            
// validate each field 
            // (- skip field ajax validation, not necessary IF we will perform an ajax form validation)
            
var r=methods._validateFields(form);

            if (
&& options.ajaxFormValidation) {
                
methods._validateFormWithAjax(formoptions);
                
// cancel form auto-submission - process with async call onAjaxFormComplete
                
return false;
            }

            if(
options.onValidationComplete) {
                
// !! ensures that an undefined return is interpreted as return false but allows a onValidationComplete() to possibly return true and have form continue processing
                
return !!options.onValidationComplete(formr);
            }
            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(keyvalue) {
                if (!
value) {
                    
status false;
                    
// break the each
                    
return false;
                }
            });
            return 
status;
        },
        
        
/**
        * Return true if the ajax field is validated
        * @param {String} fieldid
        * @param {Object} options
        * @return true, if validation passed, false if false or doesn't exist
        */
        
_checkAjaxFieldStatus: function(fieldidoptions) {
            return 
options.ajaxValidCache[fieldid] == true;
        },
        
/**
        * 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) {
            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
            
var first_err=null;
            
form.find('['+options.validateAttribute+'*=validate]').not(":disabled").each( function() {
                var 
field = $(this);
                var 
names = [];
                if ($.
inArray(field.attr('name'), names) < 0) {
                    
errorFound |= methods._validateField(fieldoptions);
                    if (
errorFound && first_err==null)
                        if (
field.is(":hidden") && options.prettySelect)
                
first_err field form.find("#" options.usePrefix field.attr('id') + options.useSuffix);
            else
                
first_err=field;
                    if (
options.doNotShowAllErrosOnSubmit)
                        return 
false;
                    
names.push(field.attr('name'));
                }
            });

            
// second, check to see if all ajax calls completed ok
            // errorFound |= !methods._checkAjaxStatus(options);

            // third, check status and scroll the container accordingly
            
form.trigger("jqv.form.result", [errorFound]);

            if (
errorFound) {
                if (
options.scroll) {
                    var 
destination=first_err.offset().top;
                    var 
fixleft first_err.offset().left;

                    
//prompt positioning adjustment support. Usage: positionType:Xshift,Yshift (for ex.: bottomLeft:+20 or bottomLeft:-20,+10)
                    
var positionType=options.promptPosition;
                    if (
typeof(positionType)=='string' && positionType.indexOf(":")!=-1)
                        
positionType=positionType.substring(0,positionType.indexOf(":"));

                    if (
positionType!="bottomRight" && positionType!="bottomLeft") {
                        var 
prompt_errmethods._getPrompt(first_err);
                        
destination=prompt_err.offset().top;
                    }

                    
// 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;
                    
if (options.isOverflown) {
                        var 
overflowDIV = $(options.overflownDIV);
                        if(!
overflowDIV.length) return false;
                        var 
scrollContainerScroll overflowDIV.scrollTop();
                        var 
scrollContainerPos = -parseInt(overflowDIV.offset().top);

                        
destination += scrollContainerScroll scrollContainerPos 5;
                        var 
scrollContainer = $(options.overflownDIV ":not(:animated)");

                        
scrollContainer.animate({ scrollTopdestination }, 1100, function(){
                            if(
options.focusFirstFieldfirst_err.focus();
                        });
                    } else {
                        $(
"html:not(:animated),body:not(:animated)").animate({
                            
scrollTopdestination,
                            
scrollLeftfixleft
                        
}, 1100, function(){
                            if(
options.focusFirstFieldfirst_err.focus();
                        });
                    }

                } else if(
options.focusFirstField)
                    
first_err.focus();
                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(formoptions) {

            var 
data form.serialize();
                            var 
type = (options.ajaxmethod) ? options.ajaxmethod "GET";
            var 
url = (options.ajaxFormValidationURL) ? options.ajaxFormValidationURL form.attr("action");
                            var 
dataType = (options.dataType) ? options.dataType "json";
            $.
ajax({
                
typetype,
                
urlurl,
                
cachefalse,
                
dataTypedataType,
                
datadata,
                
formform,
                
methodsmethods,
                
optionsoptions,
                
beforeSend: function() {
                    return 
options.onBeforeAjaxFormValidation(formoptions);
                },
                
error: function(datatransport) {
                    
methods._ajaxError(datatransport);
                },
                
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 
0json.lengthi++) {
                            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(errorFieldmsg"pass"falseoptionstrue);
                                    }
                                } 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(errorFieldmsg""falseoptionstrue);
                                }
                            }
                        }
                        
options.onAjaxFormComplete(!errorInFormformjsonoptions);
                    } else
                        
options.onAjaxFormComplete(trueform""options);
                }
            });

        },
        
/**
        * Validates field, shows prompts accordingly
        *
        * @param {jqObject}
        *            field
        * @param {Array[String]}
        *            field's validation rules
        * @param {Map}
        *            user options
        * @return false if field is valid (It is inversed for *fields*, it return false on validate and true on errors.)
        */
        
_validateField: function(fieldoptionsskipAjaxValidation) {
            if (!
field.attr("id")) {
                
field.attr("id""form-validation-field-" + $.validationEngine.fieldIdCounter);
                ++$.
validationEngine.fieldIdCounter;
            }

            if (
field.is(":hidden") && !options.prettySelect || field.parent().is(":hidden"))
                return 
false;

            var 
rulesParsing field.attr(options.validateAttribute);
            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 
promptType "";
            var 
required false;
            
options.isError false;
            
options.showArrow true;

            var 
form = $(field.closest("form"));

            for (var 
0rules.lengthi++) {
                
// Fix for adding spaces in the rules
                
rules[i] = rules[i].replace(" """); 
                var 
errorMsg undefined;
                switch (
rules[i]) {

                    case 
"required":
                        
required true;
                        
errorMsg methods._getErrorMessage(formfieldrules[i], rulesioptionsmethods._required);
                        break;
                    case 
"custom":
                        
errorMsg methods._getErrorMessage(formfieldrules[i], rulesioptionsmethods._custom);
                        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 "["+options.validateAttribute+"*=" +rules[1] +"]";
                        var 
firstOfGroup form.find(classGroup).eq(0);
                        if(
firstOfGroup[0] != field[0]){
                            
methods._validateField(firstOfGroupoptionsskipAjaxValidation); 
                            
options.showArrow true;
                            continue;
                        }
                        
errorMsg methods._getErrorMessage(formfieldrules[i], rulesioptionsmethods._groupRequired);
                        if(
errorMsg)  required true;
                        
options.showArrow false;
                        break;
                    case 
"ajax":
                        
// AJAX defaults to returning it's loading message
                        
errorMsg methods._ajax(fieldrulesioptions);
                        if (
errorMsg) {
                            
promptType "load";
                        }
                        break;
                    case 
"minSize":
                        
errorMsg methods._getErrorMessage(formfieldrules[i], rulesioptionsmethods._minSize);
                        break;
                    case 
"maxSize":
                        
errorMsg methods._getErrorMessage(formfieldrules[i], rulesioptionsmethods._maxSize);
                        break;
                    case 
"min":
                        
errorMsg methods._getErrorMessage(formfieldrules[i], rulesioptionsmethods._min);
                        break;
                    case 
"max":
                        
errorMsg methods._getErrorMessage(formfieldrules[i], rulesioptionsmethods._max);
                        break;
                    case 
"past":
                        
errorMsg methods._getErrorMessage(formfield,rules[i], rulesioptionsmethods._past);
                        break;
                    case 
"future":
                        
errorMsg methods._getErrorMessage(formfield,rules[i], rulesioptionsmethods._future);
                        break;
                    case 
"dateRange":
                        var 
classGroup "["+options.validateAttribute+"*=" rules[1] + "]";
                        
options.firstOfGroup form.find(classGroup).eq(0);
                        
options.secondOfGroup form.find(classGroup).eq(1);

                        
//if one entry out of the pair has value then proceed to run through validation
                        
if (options.firstOfGroup[0].value || options.secondOfGroup[0].value) {
                            
errorMsg methods._getErrorMessage(formfield,rules[i], rulesioptionsmethods._dateRange);
                        }
                        if (
errorMsgrequired true;
                        
options.showArrow false;
                        break;

                    case 
"dateTimeRange":
                        var 
classGroup "["+options.validateAttribute+"*=" rules[1] + "]";
                        
options.firstOfGroup form.find(classGroup).eq(0);
                        
options.secondOfGroup form.find(classGroup).eq(1);

                        
//if one entry out of the pair has value then proceed to run through validation
                        
if (options.firstOfGroup[0].value || options.secondOfGroup[0].value) {
                            
errorMsg methods._getErrorMessage(formfield,rules[i], rulesioptionsmethods._dateTimeRange);
                        }
                        if (
errorMsgrequired true;
                        
options.showArrow false;
                        break;
                    case 
"maxCheckbox":
                        
field = $(form.find("input[name='" fieldName "']"));
                        
errorMsg methods._getErrorMessage(formfieldrules[i], rulesioptionsmethods._maxCheckbox);
                        break;
                    case 
"minCheckbox":
                        
field = $(form.find("input[name='" fieldName "']"));
                        
errorMsg methods._getErrorMessage(formfieldrules[i], rulesioptionsmethods._minCheckbox);
                        break;
                    case 
"equals":
                        
errorMsg methods._getErrorMessage(formfieldrules[i], rulesioptionsmethods._equals);
                        break;
                    case 
"funcCall":
                        
errorMsg methods._getErrorMessage(formfieldrules[i], rulesioptionsmethods._funcCall);
                        break;
                    case 
"creditCard":
                        
errorMsg methods._getErrorMessage(formfieldrules[i], rulesioptionsmethods._creditCard);
                        break;
                    case 
"condRequired":
                        
errorMsg methods._getErrorMessage(formfieldrules[i], rulesioptionsmethods._condRequired);
                        if (
errorMsg !== undefined) {
                            
required true;
                        }
                        break;

                    default:
                }
                if (
errorMsg !== undefined) {
                    
promptText += errorMsg "<br/>";
                    
options.isError true;
                }

                
//if option set, stop checking validation rules after one error is found
                
if(options.showOneMessage === true && options.isError === true)
                    break;
            }
            
// If the rules required is not added, an empty field is not validated
            
if(!required && field.val().length 1options.isError false;

            
// Hack for radio/checkbox group button, the validation go into the
            // first radio/checkbox of the group
            
var fieldType field.prop("type");

            if ((
fieldType == "radio" || fieldType == "checkbox") && form.find("input[name='" fieldName "']").size() > 1) {
                
field = $(form.find("input[name='" fieldName "'][type!=hidden]:first"));
                
options.showArrow false;
            }

            if(
field.is(":hidden") && options.prettySelect) {
                
field form.find("#" options.usePrefix field.attr('id') + options.useSuffix);
            }

            if (
options.isError){
                
methods._showPrompt(fieldpromptTextpromptTypefalseoptions);
            }else{
                if (!
isAjaxValidatormethods._closePrompt(field);
            }

            if (!
isAjaxValidator) {
                
field.trigger("jqv.field.result", [fieldoptions.isErrorpromptText]);
            }

            
/* Record error */
            
var errindex = $.inArray(field[0], options.InvalidFields);
            if (
errindex == -1) {
                if (
options.isError)
                
options.InvalidFields.push(field[0]);
            } else if (!
options.isError) {
                
options.InvalidFields.splice(errindex1);
            }

            return 
options.isError;
        },
         
/********************
          * _getErrorMessage
          *
          * @param form
          * @param field
          * @param rule
          * @param rules
          * @param i
          * @param options
          * @param originalValidationMethod
          * @return {*}
          * @private
          */
         
_getErrorMessage:function (formfieldrulerulesioptionsoriginalValidationMethod) {
             
// If we are using the custon validation type, build the index for the rule.
             // Otherwise if we are doing a function call, make the call and return the object
             // that is passed back.
             
var beforeChangeRule rule;
             if (
rule == "custom") {
                 var 
custom_validation_type_index jQuery.inArray(rulerules)+ 1;
                 var 
custom_validation_type rules[custom_validation_type_index];
                 
rule "custom[" custom_validation_type "]";
             }
             var 
element_classes = (field.attr("data-validation-engine")) ? field.attr("data-validation-engine") : field.attr("class");
             var 
element_classes_array element_classes.split(" ");

             
// Call the original validation method. If we are dealing with dates, also pass the form
             
var errorMsg;
             if (
rule == "future" || rule == "past"  || rule == "maxCheckbox" || rule == "minCheckbox") {
                 
errorMsg originalValidationMethod(formfieldrulesioptions);
             } else {
                 
errorMsg originalValidationMethod(fieldrulesioptions);
             }

             
// If the original validation method returned an error and we have a custom error message,
             // return the custom message instead. Otherwise return the original error message.
             
if (errorMsg != undefined) {
                 var 
custom_message methods._getCustomErrorMessage($(field), element_classes_arraybeforeChangeRuleoptions);
                 if (
custom_message) return custom_message;
             }
             return 
errorMsg;

         },
         
_getCustomErrorMessage:function (fieldclassesruleoptions) {
            var 
custom_message false;
            var 
validityProp methods._validityProp[rule];
            if (
validityProp != undefined) {
                
custom_message field.attr("data-errormessage-"+validityProp);
                if (
custom_message != undefined
                    return 
custom_message;
            }
            
custom_message field.attr("data-errormessage");
            if (
custom_message != undefined
                return 
custom_message;
            var 
id '#' field.attr("id");
            
// If we have custom messages for the element's id, get the message for the rule from the id.
            // Otherwise, if we have custom messages for the element's classes, use the first class message we find instead.
            
if (typeof options.custom_error_messages[id] != "undefined" &&
                
typeof options.custom_error_messages[id][rule] != "undefined" ) {
                        
custom_message options.custom_error_messages[id][rule]['message'];
            } else if (
classes.length 0) {
                for (var 
0classes.length && classes.length 0i++) {
                     var 
element_class "." classes[i];
                    if (
typeof options.custom_error_messages[element_class] != "undefined" &&
                        
typeof options.custom_error_messages[element_class][rule] != "undefined") {
                            
custom_message options.custom_error_messages[element_class][rule]['message'];
                            break;
                    }
                }
            }
            if (!
custom_message &&
                
typeof options.custom_error_messages[rule] != "undefined" &&
                
typeof options.custom_error_messages[rule]['message'] != "undefined"){
                     
custom_message options.custom_error_messages[rule]['message'];
             }
             return 
custom_message;
         },
         
_validityProp: {
             
"required""value-missing",
             
"custom""custom-error",
             
"groupRequired""value-missing",
             
"ajax""custom-error",
             
"minSize""range-underflow",
             
"maxSize""range-overflow",
             
"min""range-underflow",
             
"max""range-overflow",
             
"past""type-mismatch",
             
"future""type-mismatch",
             
"dateRange""type-mismatch",
             
"dateTimeRange""type-mismatch",
             
"maxCheckbox""range-overflow",
             
"minCheckbox""range-underflow",
             
"equals""pattern-mismatch",
             
"funcCall""custom-error",
             
"creditCard""pattern-mismatch",
             
"condRequired""value-missing",
         },
        
/**
        * 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(fieldrulesioptions) {
            switch (
field.prop("type")) {
                case 
"text":
                case 
"password":
                case 
"textarea":
                case 
"file":
                case 
"select-one":
                case 
"select-multiple":
                default:

                    if (! $.
trim(field.val()) || field.val() == field.attr("data-validation-placeholder") || field.val() == field.attr("placeholder"))
                        return 
options.allrules[rules[i]].alertText;
                    break;
                case 
"radio":
                case 
"checkbox":
                    var 
form field.closest("form");
                    var 
name field.attr("name");
                    if (
form.find("input[name='" name "']:checked").size() == 0) {
                        if (
form.find("input[name='" name "']").size() == 1)
                            return 
options.allrules[rules[i]].alertTextCheckboxe;
                        else
                            return 
options.allrules[rules[i]].alertTextCheckboxMultiple;
                    }
                    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(fieldrulesioptions) {
            var 
classGroup "["+options.validateAttribute+"*=" +rules[1] +"]";
            var 
isValid false;
            
// Check all fields from the group
            
field.closest("form").find(classGroup).each(function(){
                if(!
methods._required($(this), rulesioptions)){
                    
isValid true;
                    return 
false;
                }
            }); 

            if(!
isValid) {
        return 
options.allrules[rules[i]].alertText;
      }
        },
        
/**
        * Validate rules
        *
        * @param {jqObject} field
        * @param {Array[String]} rules
        * @param {int} i rules index
        * @param {Map}
        *            user options
        * @return an error string if validation failed
        */
        
_custom: function(fieldrulesioptions) {
            var 
customRule rules[1];
            var 
rule options.allrules[customRule];
            var 
fn;
            if(!
rule) {
                
alert("jqv:custom rule not found - "+customRule);
                return;
            }
            
            if(
rule["regex"]) {
                 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;
                    
            } else if(
rule["func"]) {
                
fn rule["func"]; 
                 
                if (
typeof(fn) !== "function") {
                    
alert("jqv:custom parameter 'function' is no function - "+customRule);
                        return;
                }
                 
                if (!
fn(fieldrulesioptions))
                    return 
options.allrules[customRule].alertText;
            } else {
                
alert("jqv:custom type not allowed "+customRule);
                    return;
            }
        },
        
/**
        * 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(fieldrulesioptions) {
            var 
functionName rules[1];
            var 
fn;
            if(
functionName.indexOf('.') >-1)
            {
                var 
namespaces functionName.split('.');
                var 
scope window;
                while(
namespaces.length)
                {
                    
scope scope[namespaces.shift()];
                }
                
fn scope;
            }
            else
                
fn window[functionName] || options.customFunctions[functionName];
            if (
typeof(fn) == 'function')
                return 
fn(fieldrulesioptions);

        },
        
/**
        * 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(fieldrulesioptions) {
            var 
equalsField rules[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(fieldrulesioptions) {
            var 
max rules[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(fieldrulesioptions) {
            var 
min rules[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(fieldrulesioptions) {
            var 
min parseFloat(rules[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(fieldrulesioptions) {
            var 
max parseFloat(rules[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(formfieldrulesioptions) {

            var 
p=rules[1];
            var 
fieldAlt = $(form.find("input[name='" p.replace(/^#+/, '') + "']"));
            
var pdate;

            if (
p.toLowerCase() == "now") {
                
pdate = new Date();
            } else if (
undefined != fieldAlt.val()) {
                if (
fieldAlt.is(":disabled"))
                    return;
                
pdate methods._parseDate(fieldAlt.val());
            } else {
                
pdate 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(formfieldrulesioptions) {

            var 
p=rules[1];
            var 
fieldAlt = $(form.find("input[name='" p.replace(/^#+/, '') + "']"));
            
var pdate;

            if (
p.toLowerCase() == "now") {
                
pdate = new Date();
            } else if (
undefined != fieldAlt.val()) {
                if (
fieldAlt.is(":disabled"))
                    return;
                
pdate methods._parseDate(fieldAlt.val());
            } else {
                
pdate 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]ddd|d[1-9]dd|dd[1-9]d|ddd[1-9])$|^(?:(?:0?[1-9]|1[0-2])(/|-)(?:0?[1-9]|1d|2[0-8]))(/|-)(?:[1-9]ddd|d[1-9]dd|dd[1-9]d|ddd[1-9])$|^(0?2(/|-)29)(/|-)(?:(?:0[48]00|[13579][26]00|[2468][048]00)|(?:dd)?(?:0[48]|[2468][048]|[13579][26]))$/);
            return 
dateRegEx.test(value);
        },
        
/**
        * 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]ddd|d[1-9]dd|dd[1-9]d|ddd[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})$/);
            return 
dateTimeRegEx.test(value);
        },
        
//Checks if the start date is before the end date
        //returns true if end is later than start
        
_dateCompare: function (startend) {
            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 (fieldrulesioptions) {
            
//are not both populated
            
if ((!options.firstOfGroup[0].value && options.secondOfGroup[0].value) || (options.firstOfGroup[0].value && !options.secondOfGroup[0].value)) {
                return 
options.allrules[rules[i]].alertText options.allrules[rules[i]].alertText2;
            }

            
//are not both dates
            
if (!methods._isDate(options.firstOfGroup[0].value) || !methods._isDate(options.secondOfGroup[0].value)) {
                return 
options.allrules[rules[i]].alertText options.allrules[rules[i]].alertText2;
            }

            
//are both dates but range is off
            
if (!methods._dateCompare(options.firstOfGroup[0].valueoptions.secondOfGroup[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 (fieldrulesioptions) {
            
//are not both populated
            
if ((!options.firstOfGroup[0].value && options.secondOfGroup[0].value) || (options.firstOfGroup[0].value && !options.secondOfGroup[0].value)) {
                return 
options.allrules[rules[i]].alertText options.allrules[rules[i]].alertText2;
            }
            
//are not both dates
            
if (!methods._isDateTime(options.firstOfGroup[0].value) || !methods._isDateTime(options.secondOfGroup[0].value)) {
                return 
options.allrules[rules[i]].alertText options.allrules[rules[i]].alertText2;
            }
            
//are both dates but range is off
            
if (!methods._dateCompare(options.firstOfGroup[0].valueoptions.secondOfGroup[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(formfieldrulesioptions) {

            var 
nbCheck rules[1];
            var 
groupname field.attr("name");
            var 
groupSize form.find("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(formfieldrulesioptions) {

            var 
nbCheck rules[1];
            var 
groupname field.attr("name");
            var 
groupSize form.find("input[name='" groupname "']:checked").size();
            if (
groupSize nbCheck) {
                
options.showArrow false;
                return 
options.allrules.minCheckbox.alertText " " nbCheck " " options.allrules.minCheckbox.alertText2;
            }
        },
        
/**
        * Checks that it is a valid credit card number according to the
        * Luhn checksum algorithm.
        *
        * @param {jqObject} field
        * @param {Array[String]} rules
        * @param {int} i rules index
        * @param {Map}
        *            user options
        * @return an error string if validation failed
        */
        
_creditCard: function(fieldrulesioptions) {
            
//spaces and dashes may be valid characters, but must be stripped to calculate the checksum.
            
var valid falsecardNumber field.val().replace(/ +/g'').replace(/-+/g'');

            var 
numDigits cardNumber.length;
            if (
numDigits >= 14 && numDigits <= 16 && parseInt(cardNumber) > 0) {

                var 
sum 0numDigits 1pos 1digitluhn = new String();
                do {
                    
digit parseInt(cardNumber.charAt(i));
                    
luhn += (pos++ % == 0) ? digit digit;
                } while (--
>= 0)

                for (
0luhn.lengthi++) {
                    
sum += parseInt(luhn.charAt(i));
                }
                
valid sum 10 == 0;
            }
            if (!
valid) return options.allrules.creditCard.alertText;
        },
        
/**
        * 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(fieldrulesioptions) {

             var 
errorSelector rules[1];
             var 
rule options.allrules[errorSelector];
             var 
extraData rule.extraData;
             var 
extraDataDynamic rule.extraDataDynamic;
             var 
data = {
                
"fieldId" field.attr("id"),
                
"fieldValue" field.val()
             };

             if (
typeof extraData === "object") {
                $.
extend(dataextraData);
             } else if (
typeof extraData === "string") {
                var 
tempData extraData.split("&");
                for(var 
0tempData.lengthi++) {
                    var 
values tempData[i].split("=");
                    if (
values[0] && values[0]) {
                        
data[values[0]] = values[1];
                    }
                }
             }

             if (
extraDataDynamic) {
                 var 
tmpData = [];
                 var 
domIds String(extraDataDynamic).split(",");
                 for (var 
0domIds.lengthi++) {
                     var 
id domIds[i];
                     if ($(
id).length) {
                         var 
inputValue field.closest("form").find(id).val();
                         var 
keyValue id.replace('#''') + '=' escape(inputValue);
                         
data[id.replace('#''')] = inputValue;
                     }
                 }
             }
             
             
// If a field change event triggered this we want to clear the cache for this ID
             
if (options.eventTrigger == "field") {
                
delete(options.ajaxValidCache[field.attr("id")]);
             }

             
// If there is an error or if the the field is already validated, do not re-execute AJAX
             
if (!options.isError && !methods._checkAjaxFieldStatus(field.attr("id"), options)) {
                 $.
ajax({
                     
typeoptions.ajaxFormValidationMethod,
                     
urlrule.url,
                     
cachefalse,
                     
dataType"json",
                     
datadata,
                     
fieldfield,
                     
rulerule,
                     
methodsmethods,
                     
optionsoptions,
                     
beforeSend: function() {},
                     
error: function(datatransport) {
                         
methods._ajaxError(datatransport);
                     },
                     
success: function(json) {

                         
// asynchronously called on success, data is the json answer from the server
                         
var errorFieldId json[0];
                         
//var errorField = $($("#" + errorFieldId)[0]);
                         
var errorField = $($("input[id='" 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(errorFieldmsg""trueoptions);
                             } else {
                                 
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(errorFieldmsg"pass"trueoptions);
                                 else
                                    
methods._closePrompt(errorField);
                                
                                 
// If a submit form triggered this, we want to re-submit the form
                                 
if (options.eventTrigger == "submit")
                                    
field.closest("form").submit();
                             }
                         }
                         
errorField.trigger("jqv.field.result", [errorFieldoptions.isErrormsg]);
                     }
                 });
                 
                 return 
rule.alertTextLoad;
             }
         },
        
/**
        * Common method to handle ajax errors
        *
        * @param {Object} data
        * @param {Object} transport
        */
        
_ajaxError: function(datatransport) {
            if(
data.status == && 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(fieldpromptTexttypeajaxedoptionsajaxform) {
             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(ajaxformprompt false;
             if (
prompt)
                
methods._updatePrompt(fieldpromptpromptTexttypeajaxedoptions);
             else
                
methods._buildPrompt(fieldpromptTexttypeajaxedoptions);
         },
        
/**
        * 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(fieldpromptTexttypeajaxedoptions) {

            
// 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
            
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");
                    break;
                default:
                    
/* it has error  */
                    //alert("unknown popup type:"+type);
            
}
            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");

                
//prompt positioning adjustment support. Usage: positionType:Xshift,Yshift (for ex.: bottomLeft:+20 or bottomLeft:-20,+10)
                
var positionType=field.data("promptPosition") || options.promptPosition;
                if (
typeof(positionType)=='string'
                {
                    var 
pos=positionType.indexOf(":");
                    if(
pos!=-1)
                        
positionType=positionType.substring(0,pos);
                }

                switch (
positionType) {
                    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;
                }
            }
            
// Modify z-indexes  for jquery ui
            
if (field.closest('.ui-dialog').length)
                
prompt.addClass('formErrorInsideDialog');

            
prompt.css({
                
"opacity"0,
                
'position':'absolute'
            
});
            
field.before(prompt);
            
            var 
pos methods._calculatePosition(fieldpromptoptions);
            
prompt.css({
                
"top"pos.callerTopPosition,
                
"left"pos.callerleftPosition,
                
"marginTop"pos.marginTopSize,
                
"opacity"0
            
}).data("callerField"field);

            if (
options.autoHidePrompt) {
                
setTimeout(function(){
                    
prompt.animate({
                        
"opacity"0
                    
},function(){
                        
prompt.closest('.formErrorOuter').remove();
                        
prompt.remove();
                    });
                }, 
options.autoHideDelay);
            } 
            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(fieldpromptpromptTexttypeajaxedoptionsnoAnimation) {

            if (
prompt) {
                if (
typeof type !== "undefined") {
                    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(fieldpromptoptions);
                var 
css = {"top"pos.callerTopPosition,
                
"left"pos.callerleftPosition,
                
"marginTop"pos.marginTopSize};

                if (
noAnimation)
                    
prompt.css(css);
                else
                    
prompt.animate(css);
            }
        },
        
/**
        * 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.parent('.formErrorOuter').remove();
                     
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 
formId = $(field).closest('form').attr('id');
            var 
className methods._getClassName(field.attr("id")) + "formError";
                var 
match = $("." methods._escapeExpression(className) + '.parentForm' formId)[0];
            if (
match)
            return $(
match);
        },
        
/**
          * Returns the escapade classname
          *
          * @param {selector}
          *            className
          */
          
_escapeExpression: function (selector) {
              return 
selector.replace(/([#;&,.+*~':"!^$[]()=>|])/g, "\$1");
          
},
        
/**
         * returns true if we are in a RTLed document
         *
         * @param {jqObject} field
         */
        
isRTL: function(field)
        {
            var 
$document = $(document);
            var 
$body = $('body');
            var 
rtl =
                (
field && field.hasClass('rtl')) ||
                (
field && (field.attr('dir') || '').toLowerCase()==='rtl') ||
                
$document.hasClass('rtl') ||
                (
$document.attr('dir') || '').toLowerCase()==='rtl' ||
                
$body.hasClass('rtl') ||
                (
$body.attr('dir') || '').toLowerCase()==='rtl';
            return 
Boolean(rtl);
        },
        
/**
        * Calculates prompt position
        *
        * @param {jqObject}
        *            field
        * @param {jqObject}
        *            the prompt
        * @param {Map}
        *            options
        * @return positions
        */
        
_calculatePosition: function (fieldpromptElmtoptions) {

            var 
promptTopPositionpromptleftPositionmarginTopSize;
            var 
fieldWidth     field.width();
            var 
fieldLeft     field.position().left
            var 
fieldTop     =  field.position().top;
            var 
fieldHeight     =  field.height();    
            var 
promptHeight promptElmt.height();


            
// is the form contained in an overflown container?
            
promptTopPosition promptleftPosition 0;
            
// compensation for the arrow
            
marginTopSize = -promptHeight;
        

            
//prompt positioning adjustment support
            //now you can adjust prompt position
            //usage: positionType:Xshift,Yshift
            //for example:
            //   bottomLeft:+20 means bottomLeft position shifted by 20 pixels right horizontally
            //   topRight:20, -15 means topRight position shifted by 20 pixels to right and 15 pixels to top
            //You can use +pixels, - pixels. If no sign is provided than + is default.
            
var positionType=field.data("promptPosition") || options.promptPosition;
            var 
shift1="";
            var 
shift2="";
            var 
shiftX=0;
            var 
shiftY=0;
            if (
typeof(positionType)=='string') {
                
//do we have any position adjustments ?
                
if (positionType.indexOf(":")!=-1) {
                    
shift1=positionType.substring(positionType.indexOf(":")+1);
                    
positionType=positionType.substring(0,positionType.indexOf(":"));

                    
//if any advanced positioning will be needed (percents or something else) - parser should be added here
                    //for now we use simple parseInt()

                    //do we have second parameter?
                    
if (shift1.indexOf(",") !=-1) {
                        
shift2=shift1.substring(shift1.indexOf(",") +1);
                        
shift1=shift1.substring(0,shift1.indexOf(","));
                        
shiftY=parseInt(shift2);
                        if (
isNaN(shiftY)) shiftY=0;
                    };

                    
shiftX=parseInt(shift1);
                    if (
isNaN(shift1)) shift1=0;

                };
            };

            
            switch (
positionType) {
                default:
                case 
"topRight":
                    
promptleftPosition +=  fieldLeft fieldWidth 30;
                    
promptTopPosition +=  fieldTop;
                    break;

                case 
"topLeft":
                    
promptTopPosition +=  fieldTop;
                    
promptleftPosition += fieldLeft
                    break;

                case 
"centerRight":
                    
promptTopPosition fieldTop+4;
                    
marginTopSize 0;
                    
promptleftPositionfieldLeft field.outerWidth(true)+5;
                    break;
                case 
"centerLeft":
                    
promptleftPosition fieldLeft - (promptElmt.width() + 2);
                    
promptTopPosition fieldTop+4;
                    
marginTopSize 0;
                    
                    break;

                case 
"bottomLeft":
                    
promptTopPosition fieldTop field.height() + 5;
                    
marginTopSize 0;
                    
promptleftPosition fieldLeft;
                    break;
                case 
"bottomRight":
                    
promptleftPosition fieldLeft fieldWidth 30;
                    
promptTopPosition =  fieldTop +  field.height() + 5;
                    
marginTopSize 0;
            };

        

            
//apply adjusments if any
            
promptleftPosition += shiftX;
            
promptTopPosition  += shiftY;

            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(formoptions) {

             
// 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(true,{},$.validationEngine.defaults,options);

             
form.data('jqv'userOptions);
             return 
userOptions;
         },

         
/**
         * Removes forbidden characters from class name
         * @param {String} className
         */
         
_getClassName: function(className) {
             if(
className)
                 return 
className.replace(/:/g"_").replace(/./g"_");
                 },

        
/**
        * Conditionally required field
        *
        * @param {jqObject} field
        * @param {Array[String]} rules
        * @param {int} i rules index
        * @param {Map}
        * user options
        * @return an error string if validation failed
        */
        
_condRequired: function(fieldrulesioptions) {
            var 
idxdependingField;

            for(
idx = (1); idx rules.lengthidx++) {
                
dependingField jQuery("#" rules[idx]).first();

                
/* Use _required for determining wether dependingField has a value.
                 * There is logic there for handling all field types, and default value; so we won't replicate that here
                 */
                
if (dependingField.length && methods._required(dependingField, ["required"], 0options) == undefined) {
                    
/* We now know any of the depending fields has a value,
                     * so we can validate this field as per normal required code
                     */
                    
return methods._required(field, ["required"], 0options);
                }
            }
        }
        };

     
/**
     * 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 form;  // 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 != "hide" && method != "hideAll")
             
methods.init.apply(form);

             return 
methods[method].apply(form, Array.prototype.slice.call(arguments1));
         } else if (
typeof method == 'object' || !method) {

             
// default constructor with or without arguments
             
methods.init.apply(formarguments);
             return 
methods.attach.apply(form);
         } else {
             $.
error('Method ' method ' does not exist in jQuery.validationEngine');
         }
    };



    
// LEAK GLOBAL OPTIONS
    
$.validationEngine= {fieldIdCounter0,defaults:{

        
// Name of the event triggering field validation
        
validationEventTrigger"blur",
        
// Automatically scroll viewport to the first error
        
scrolltrue,
        
// Focus on the first input
        
focusFirstField: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
        
inlineAjaxfalse,
        
// if set to true, the form data is sent asynchronously via ajax to the form.action url (get)
        
ajaxFormValidationfalse,
        
// The url to send the submit ajax validation (default to action)
        
ajaxFormValidationURLfalse,
        
// HTTP method used for ajax validation
        
ajaxFormValidationMethod'get',
        
// Ajax form validation callback method: boolean onComplete(form, status, errors, options)
        // retuns false if the form.submit event needs to be canceled.
        
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
        
onValidationCompletefalse,

        
// Used when you have a form fields too close and the errors messages are on top of other disturbing viewing messages
        
doNotShowAllErrosOnSubmitfalse,
        
// Object where you store custom messages to override the default error messages
        
custom_error_messages:{},
        
// true if you want to vind the input fields
        
bindedtrue,
        
// set to true, when the prompt arrow needs to be displayed
        
showArrowtrue,
        
// did one of the validation fail ? kept global to stop further ajax validations
        
isErrorfalse,
        
// 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: {},
        
// Auto update prompt position after window resize
        
autoPositionUpdatefalse,

        
InvalidFields: [],
        
onSuccessfalse,
        
onFailurefalse,
        
// Auto-hide prompt
        
autoHidePromptfalse,
        
// Delay before auto-hide
        
autoHideDelay10000,
        
// Fade out duration while hiding the validations
        
fadeDuration0.3,
    
// Use Prettify select library
    
prettySelectfalse,
    
// Custom ID uses prefix
    
usePrefix"",
    
// Custom ID uses suffix
    
useSuffix"",
    
// Only show one message per error prompt
    
showOneMessagefalse
    
}};
    $(function(){$.
validationEngine.defaults.promptPosition methods.isRTL()?'topLeft':"topRight"});
})(
jQuery);
?>
Онлайн: 1
Реклама