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

    
"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(form, options);
                
// bind all formError elements to close on click
                
$(document).on("click", ".formError", 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) {

            var 
form = this;
            var 
options;

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

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

                
// delegate fields
                
form.on(options.validationEventTrigger, "[" + options.validateAttribute + "*=validate]:not([type=checkbox]):not([type=radio]):not(.datepicker)", methods._onFieldEvent);
                
form.on("click", "[" + options.validateAttribute + "*=validate][type=checkbox],[" + options.validateAttribute + "*=validate][type=radio]", methods._onFieldEvent);
                
form.on(options.validationEventTrigger, "[" + options.validateAttribute + "*=validate][class*=datepicker]", {"delay": 300}, methods._onFieldEvent);
            }
            if (
options.autoPositionUpdate) {
                $(
window).bind("resize", {
                    
"noAnimation": true,
                    
"formElem": form
                
}, methods.updatePromptsPosition);
            }
            
form.on("click", "a[data-validation-engine-skip], a[class*='validate-skip'], button[data-validation-engine-skip], button[class*='validate-skip'], input[data-validation-engine-skip], input[class*='validate-skip']", methods._submitButtonClick);
            
form.removeData('jqv_submitButton');

            
// bind form.submit
            
form.on("submit", methods._onSubmitEvent);
            return 
this;
        },
        
/**
         * Unregisters any bindings that may point to jQuery.validaitonEngine
         */
        
detach: function () {

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

            
// unbind fields
            
form.off(options.validationEventTrigger, "[" + options.validateAttribute + "*=validate]:not([type=checkbox]):not([type=radio]):not(.datepicker)", methods._onFieldEvent);
            
form.off("click", "[" + options.validateAttribute + "*=validate][type=checkbox],[" + options.validateAttribute + "*=validate][type=radio]", methods._onFieldEvent);
            
form.off(options.validationEventTrigger, "[" + options.validateAttribute + "*=validate][class*=datepicker]", methods._onFieldEvent);

            
// unbind form.submit
            
form.off("submit", methods._onSubmitEvent);
            
form.removeData('jqv');

            
form.off("click", "a[data-validation-engine-skip], a[class*='validate-skip'], button[data-validation-engine-skip], button[class*='validate-skip'], input[data-validation-engine-skip], input[class*='validate-skip']", methods._submitButtonClick);
            
form.removeData('jqv_submitButton');

            if (
options.autoPositionUpdate)
                $(
window).off("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 () {
            var 
element = $(this);
            var 
valid = null;

            if (
element.is("form") || element.hasClass("validationEngineContainer")) {
                if (
element.hasClass('validating')) {
                    
// form is already validating.
                    // Should abort old validation and start new one. I don't know how to implement it.
                    
return false;
                } else {
                    
element.addClass('validating');
                    var 
options = element.data('jqv');
                    var 
valid = methods._validateFields(this);

                    
// If the form doesn't validate, clear the 'validating' class before the user has a chance to submit again
                    
setTimeout(function () {
                        
element.removeClass('validating');
                    }, 
100);
                    if (
valid && options.onSuccess) {
                        
options.onSuccess();
                    } else if (!
valid && options.onFailure) {
                        
options.onFailure();
                    }
                }
            } else if (
element.is('form') || element.hasClass('validationEngineContainer')) {
                
element.removeClass('validating');
            } else {
                
// field validation
                
var form = element.closest('form, .validationEngineContainer'),
                    
options = (form.data('jqv')) ? form.data('jqv') : $.validationEngine.defaults,
                    
valid = methods._validateField(element, options);
            }
            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(form, valid);
            }
            return 
valid;
        },
        
/**
         *  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, .validationEngineContainer'));

            var 
options = form.data('jqv');
            
// No option, take default one
            
if (!options)
                
options = methods._saveOptions(form, options);
            
form.find('[' + options.validateAttribute + '*=validate]').not(":disabled").each(function () {
                var 
field = $(this);
                if (
options.prettySelect && field.is(":hidden"))
                    
field = form.find("#" + options.usePrefix + field.attr('id') + options.useSuffix);
                var 
prompt = methods._getPrompt(field);
                var 
promptText = $(prompt).find(".formErrorContent").html();

                if (
prompt)
                    
methods._updatePrompt(field, $(prompt), promptText, undefined, false, options, noAnimation);
            });
            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 (promptText, type, promptPosition, showArrow) {
            var 
form = this.closest('form, .validationEngineContainer');
            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);
            return 
this;
        },
        
/**
         * Closes form error prompts, CAN be invidual
         */
        
hide: function () {
            var 
form = $(this).closest('form, .validationEngineContainer');
            var 
options = form.data('jqv');
            
// No option, take default one
            
if (!options)
                
options = methods._saveOptions(form, options);
            var 
fadeDuration = (options && options.fadeDuration) ? options.fadeDuration : 0.3;
            var 
closingtag;

            if ($(
this).is("form") || $(this).hasClass("validationEngineContainer")) {
                
closingtag = "parentForm" + methods._getClassName($(this).attr("id"));
            } else {
                
closingtag = methods._getClassName($(this).attr("id")) + "formError";
            }
            $(
'.' + closingtag).fadeTo(fadeDuration, 0.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 : 300;
            $(
'.formError').fadeTo(duration, 300, 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, .validationEngineContainer');
            var 
options = form.data('jqv');
            
// No option, take default one
            
if (!options)
                
options = methods._saveOptions(form, options);
            
options.eventTrigger = "field";
            
// 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');

            
//check if it is trigger from skipped button
            
if (form.data("jqv_submitButton")) {
                var 
submitButton = $("#" + form.data("jqv_submitButton"));
                if (
submitButton) {
                    if (
submitButton.length > 0) {
                        if (
submitButton.hasClass("validate-skip") || submitButton.attr("data-validation-engine-skip") == "true")
                            return 
true;
                    }
                }
            }

            
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 (
r && options.ajaxFormValidation) {
                
methods._validateFormWithAjax(form, options);
                
// 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(form, r);
            }
            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;
        },

        
/**
         * 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 (fieldid, options) {
            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(field, options);
                    if (
errorFound && first_err == null)
                        if (
field.is(":hidden") && options.prettySelect)
                            
first_err = field = form.find("#" + options.usePrefix + methods._jqSelector(field.attr('id')) + options.useSuffix);
                        else {

                            
//Check if we need to adjust what element to show the prompt on
                            //and and such scroll to instead
                            
if (field.data('jqv-prompt-at') instanceof jQuery) {
                                
field = field.data('jqv-prompt-at');
                            } else if (
field.data('jqv-prompt-at')) {
                                
field = $(field.data('jqv-prompt-at'));
                            }
                            
first_err = field;
                        }
                    if (
options.doNotShowAllErrosOnSubmit)
                        return 
false;
                    
names.push(field.attr('name'));

                    
//if option set, stop checking validation rules after one error is found
                    
if (options.showOneMessage == true && errorFound) {
                        return 
false;
                    }
                }
            });

            
// 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_err = methods._getPrompt(first_err);
                        if (
prompt_err) {
                            
destination = prompt_err.offset().top;
                        }
                    }

                    
// Offset the amount the page scrolls by an amount in px to accomodate fixed elements at top of page
                    
if (options.scrollOffset) {
                        
destination -= options.scrollOffset;
                    }

                    
// 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({ scrollTop: destination }, 1100, function () {
                            if (
options.focusFirstField) first_err.focus();
                        });

                    } else {
                        $(
"html, body").animate({
                            
scrollTop: destination
                        
}, 1100, function () {
                            if (
options.focusFirstField) first_err.focus();
                        });
                        $(
"html, body").animate({scrollLeft: fixleft}, 1100)
                    }

                } 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 (form, options) {

            var 
data = form.serialize();
            var 
type = (options.ajaxFormValidationMethod) ? options.ajaxFormValidationMethod : "GET";
            var 
url = (options.ajaxFormValidationURL) ? options.ajaxFormValidationURL : form.attr("action");
            var 
dataType = (options.dataType) ? options.dataType : "json";
            $.
ajax({
                
type: type,
                
url: url,
                
cache: false,
                
dataType: dataType,
                
data: data,
                
form: form,
                
methods: methods,
                
options: options,
                
beforeSend: function () {
                    return 
options.onBeforeAjaxFormValidation(form, options);
                },
                
error: function (data, transport) {
                    if (
options.onFailure) {
                        
options.onFailure(data, transport);
                    } else {
                        
methods._ajaxError(data, transport);
                    }
                },
                
success: function (json) {
                    if ((
dataType == "json") && (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;
                                        }
                                        if (
options.showPrompts) 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;
                                    }
                                    if (
options.showPrompts) methods._showPrompt(errorField, msg, "", false, options, true);
                                }
                            }
                        }
                        
options.onAjaxFormComplete(!errorInForm, form, json, options);
                    } else
                        
options.onAjaxFormComplete(true, form, json, 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 (field, options, skipAjaxValidation) {
            if (!
field.attr("id")) {
                
field.attr("id", "form-validation-field-" + $.validationEngine.fieldIdCounter);
                ++$.
validationEngine.fieldIdCounter;
            }

            if (!
options.validateNonVisibleFields && (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;
            var 
limitErrors = false;
            
options.isError = false;
            
options.showArrow = true;

            
// If the programmer wants to limit the amount of error messages per field,
            
if (options.maxErrorsPerField > 0) {
                
limitErrors = true;
            }

            var 
form = $(field.closest("form, .validationEngineContainer"));
            
// Fix for adding spaces in the rules
            
for (var i = 0; i < rules.length; i++) {
                
rules[i] = rules[i].replace(" ", "");
                
// Remove any parsing errors
                
if (rules[i] === '') {
                    
delete rules[i];
                }
            }

            for (var 
i = 0, field_errors = 0; i < rules.length; i++) {

                
// If we are limiting errors, and have hit the max, break
                
if (limitErrors && field_errors >= options.maxErrorsPerField) {
                    
// If we haven't hit a required yet, check to see if there is one in the validation rules for this
                    // field and that it's index is greater or equal to our current index
                    
if (!required) {
                        var 
have_required = $.inArray('required', rules);
                        
required = (have_required != -1 && have_required >= i);
                    }
                    break;
                }


                var 
errorMsg = undefined;
                switch (
rules[i]) {

                    case 
"required":
                        
required = true;
                        
errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._required);
                        break;
                    case 
"custom":
                        
errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._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[i + 1] + "]";
                        var 
firstOfGroup = form.find(classGroup).eq(0);
                        if (
firstOfGroup[0] != field[0]) {

                            
methods._validateField(firstOfGroup, options, skipAjaxValidation);
                            
options.showArrow = true;

                        }
                        
errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._groupRequired);
                        if (
errorMsg)  required = true;
                        
options.showArrow = false;
                        break;
                    case 
"ajax":
                        
// AJAX defaults to returning it's loading message
                        
errorMsg = methods._ajax(field, rules, i, options);
                        if (
errorMsg) {
                            
promptType = "load";
                        }
                        break;
                    case 
"minSize":
                        
errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._minSize);
                        break;
                    case 
"maxSize":
                        
errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._maxSize);
                        break;
                    case 
"min":
                        
errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._min);
                        break;
                    case 
"max":
                        
errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._max);
                        break;
                    case 
"past":
                        
errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._past);
                        break;
                    case 
"future":
                        
errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._future);
                        break;
                    case 
"dateRange":
                        var 
classGroup = "[" + options.validateAttribute + "*=" + rules[i + 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(form, field, rules[i], rules, i, options, methods._dateRange);
                        }
                        if (
errorMsg) required = true;
                        
options.showArrow = false;
                        break;

                    case 
"dateTimeRange":
                        var 
classGroup = "[" + options.validateAttribute + "*=" + rules[i + 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(form, field, rules[i], rules, i, options, methods._dateTimeRange);
                        }
                        if (
errorMsg) required = true;
                        
options.showArrow = false;
                        break;
                    case 
"maxCheckbox":
                        
field = $(form.find("input[name='" + fieldName + "']"));
                        
errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._maxCheckbox);
                        break;
                    case 
"minCheckbox":
                        
field = $(form.find("input[name='" + fieldName + "']"));
                        
errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._minCheckbox);
                        break;
                    case 
"equals":
                        
errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._equals);
                        break;
                    case 
"funcCall":
                        
errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._funcCall);
                        break;
                    case 
"creditCard":
                        
errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._creditCard);
                        break;
                    case 
"condRequired":
                        
errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._condRequired);
                        if (
errorMsg !== undefined) {
                            
required = true;
                        }
                        break;
                    case 
"funcCallRequired":
                        
errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._funcCallRequired);
                        if (
errorMsg !== undefined) {
                            
required = true;
                        }
                        break;

                    default:
                }

                var 
end_validation = false;

                
// If we were passed back an message object, check what the status was to determine what to do
                
if (typeof errorMsg == "object") {
                    switch (
errorMsg.status) {
                        case 
"_break":
                            
end_validation = true;
                            break;
                        
// If we have an error message, set errorMsg to the error message
                        
case "_error":
                            
errorMsg = errorMsg.message;
                            break;
                        
// If we want to throw an error, but not show a prompt, return early with true
                        
case "_error_no_prompt":
                            return 
true;
                            break;
                        
// Anything else we continue on
                        
default:
                            break;
                    }
                }

                
//funcCallRequired, first in rules, and has error, skip anything else
                
if (i == 0 && str.indexOf('funcCallRequired') == 0 && errorMsg !== undefined) {
                    
promptText += errorMsg + "<br/>";
                    
options.isError = true;
                    
field_errors++;
                    
end_validation = true;
                }

                
// If it has been specified that validation should end now, break
                
if (end_validation) {
                    break;
                }

                
// If we have a string, that means that we have an error, so add it to the error message.
                
if (typeof errorMsg == 'string') {
                    
promptText += errorMsg + "<br/>";
                    
options.isError = true;
                    
field_errors++;
                }
            }
            
// If the rules required is not added, an empty field is not validated
            //the 3rd condition is added so that even empty password fields should be equal
            //otherwise if one is filled and another left empty, the "equal" condition would fail
            //which does not make any sense
            
if (!required && !(field.val()) && field.val().length < 1 && $.inArray('equals', rules) < 0) options.isError = false;

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

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

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

            if (
options.isError && options.showPrompts) {
                
methods._showPrompt(field, promptText, promptType, false, options);
            } else {
                if (!
isAjaxValidator) methods._closePrompt(field);
            }

            if (!
isAjaxValidator) {
                
field.trigger("jqv.field.result", [field, options.isError, promptText]);
            }

            
/* 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(errindex, 1);
            }

            
methods._handleStatusCssClasses(field, options);

            
/* run callback function for each field */
            
if (options.isError && options.onFieldFailure)
                
options.onFieldFailure(field);

            if (!
options.isError && options.onFieldSuccess)
                
options.onFieldSuccess(field);

            return 
options.isError;
        },
        
/**
         * Handling css classes of fields indicating result of validation
         *
         * @param {jqObject}
         *            field
         * @param {Array[String]}
         *            field's validation rules
         * @private
         */
        
_handleStatusCssClasses: function (field, options) {
            
/* remove all classes */
            
if (options.addSuccessCssClassToField)
                
field.removeClass(options.addSuccessCssClassToField);

            if (
options.addFailureCssClassToField)
                
field.removeClass(options.addFailureCssClassToField);

            
/* Add classes */
            
if (options.addSuccessCssClassToField && !options.isError)
                
field.addClass(options.addSuccessCssClassToField);

            if (
options.addFailureCssClassToField && options.isError)
                
field.addClass(options.addFailureCssClassToField);
        },

        
/********************
         * _getErrorMessage
         *
         * @param form
         * @param field
         * @param rule
         * @param rules
         * @param i
         * @param options
         * @param originalValidationMethod
         * @return {*}
         * @private
         */
        
_getErrorMessage: function (form, field, rule, rules, i, options, originalValidationMethod) {
            
// 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 rule_index = jQuery.inArray(rule, rules);
            if (
rule === "custom" || rule === "funcCall" || rule === "funcCallRequired") {
                var 
custom_validation_type = rules[rule_index + 1];
                
rule = rule + "[" + custom_validation_type + "]";
                
// Delete the rule from the rules array so that it doesn't try to call the
                // same rule over again
                
delete(rules[rule_index]);
            }
            
// Change the rule to the composite rule, if it was different from the original
            
var alteredRule = rule;


            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 or checkboxes, also pass the form
            
var errorMsg;
            if (
rule == "future" || rule == "past" || rule == "maxCheckbox" || rule == "minCheckbox") {
                
errorMsg = originalValidationMethod(form, field, rules, i, options);
            } else {
                
errorMsg = originalValidationMethod(field, rules, i, options);
            }

            
// 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_array, alteredRule, options);
                if (
custom_message) errorMsg = custom_message;
            }
            return 
errorMsg;

        },
        
_getCustomErrorMessage: function (field, classes, rule, options) {
            var 
custom_message = false;
            var 
validityProp = /^custom[.*]$/.test(rule) ? methods._validityProp["custom"] : methods._validityProp[rule];
            
// If there is a validityProp for this rule, check to see if the field has an attribute for it
            
if (validityProp != undefined) {
                
custom_message = field.attr("data-errormessage-" + validityProp);
                
// If there was an error message for it, return the message
                
if (custom_message != undefined)
                    return 
custom_message;
            }
            
custom_message = field.attr("data-errormessage");
            
// If there is an inline custom error message, return it
            
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 
i = 0; i < classes.length && classes.length > 0; i++) {
                    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",
            
"funcCallRequired": "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
         * @param {bool} condRequired flag when method is used for internal purpose in condRequired check
         * @return an error string if validation failed
         */
        
_required: function (field, rules, i, options, condRequired) {
            switch (
field.prop("type")) {
                case 
"radio":
                case 
"checkbox":
                    
// new validation style to only check dependent field
                    
if (condRequired) {
                        if (!
field.prop('checked')) {
                            return 
options.allrules[rules[i]].alertTextCheckboxMultiple;
                        }
                        break;
                    }
                    
// old validation style
                    
var form = field.closest("form, .validationEngineContainer");
                    var 
name = field.attr("name");
                    if (
form.find("input[name='" + name + "']:checked").size() == 0) {
                        if (
form.find("input[name='" + name + "']:visible").size() == 1)
                            return 
options.allrules[rules[i]].alertTextCheckboxe;
                        else
                            return 
options.allrules[rules[i]].alertTextCheckboxMultiple;
                    }
                    break;
                case 
"text":
                case 
"password":
                case 
"textarea":
                case 
"file":
                case 
"select-one":
                case 
"select-multiple":
                default:
                    var 
field_val = $.trim(field.val());
                    var 
dv_placeholder = $.trim(field.attr("data-validation-placeholder"));
                    var 
placeholder = $.trim(field.attr("placeholder"));
                    if (
                        ( !
field_val                                    )
                            || ( 
dv_placeholder && field_val == dv_placeholder )
                            || ( 
placeholder && field_val == placeholder    )
                        ) {
                        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 = "[" + options.validateAttribute + "*=" + rules[i + 1] + "]";
            var 
isValid = false;
            
// Check all fields from the group
            
field.closest("form, .validationEngineContainer").find(classGroup).each(function () {
                if (!
methods._required($(this), rules, i, options)) {
                    
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 (field, rules, i, options) {
            var 
customRule = rules[i + 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(field, rules, i, options))
                    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 (field, rules, i, options) {
            var 
functionName = rules[i + 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(field, rules, i, options);

        },
        
_funcCallRequired: function (field, rules, i, options) {
            return 
methods._funcCall(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 (form, field, rules, i, options) {

            var 
p = rules[i + 1];
            var 
fieldAlt = $(form.find("*[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 (form, field, rules, i, options) {

            var 
p = rules[i + 1];
            var 
fieldAlt = $(form.find("*[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 (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 (field, rules, i, options) {
            
//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].value, options.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 (field, rules, i, options) {
            
//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].value, options.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 (form, field, rules, i, options) {

            var 
nbCheck = rules[i + 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 (form, field, rules, i, options) {

            var 
nbCheck = rules[i + 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 (field, rules, i, options) {
            
//spaces and dashes may be valid characters, but must be stripped to calculate the checksum.
            
var valid = false, cardNumber = field.val().replace(/ +/g, '').replace(/-+/g, '');

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

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

                for (
i = 0; i < luhn.length; i++) {
                    
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 (field, rules, i, options) {

            var 
errorSelector = rules[i + 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(data, extraData);
            } else if (
typeof extraData === "string") {
                var 
tempData = extraData.split("&");
                for (var 
i = 0; i < tempData.length; i++) {
                    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 
i = 0; i < domIds.length; i++) {
                    var 
id = domIds[i];
                    if ($(
id).length) {
                        var 
inputValue = field.closest("form, .validationEngineContainer").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({
                    
type: options.ajaxFormValidationMethod,
                    
url: rule.url,
                    
cache: false,
                    
dataType: "json",
                    
data: data,
                    
field: field,
                    
rule: rule,
                    
methods: methods,
                    
options: options,
                    
beforeSend: function () {
                    },
                    
error: function (data, transport) {
                        if (
options.onFailure) {
                            
options.onFailure(data, transport);
                        } else {
                            
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]);
                        
var errorField = $("#" + errorFieldId).eq(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;

                                if (
options.showPrompts) methods._showPrompt(errorField, msg, "", true, options);
                            } 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;

                                if (
options.showPrompts) {
                                    
// see if we should display a green prompt
                                    
if (msg)
                                        
methods._showPrompt(errorField, msg, "pass", true, options);
                                    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", [errorField, options.isError, msg]);
                    }
                });

                return 
rule.alertTextLoad;
            }
        },
        
/**
         * 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("/");
            if (
dateParts == d) {
                
dateParts = d.split(".");
                return new 
Date(dateParts[2], (dateParts[1] - 1), dateParts[0]);
            }
            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) {
            
//Check if we need to adjust what element to show the prompt on
            
if (field.data('jqv-prompt-at') instanceof jQuery) {
                
field = field.data('jqv-prompt-at');
            } else if (
field.data('jqv-prompt-at')) {
                
field = $(field.data('jqv-prompt-at'));
            }

            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;
            
// Check that there is indded text
            
if ($.trim(promptText)) {
                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
            
prompt.addClass("parentForm" + methods._getClassName(field.closest('form, .validationEngineContainer').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);

            
// determine position type
            
var positionType = field.data("promptPosition") || options.promptPosition;

            
// 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)
                
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;
                }
            }
            
// Add custom prompt class
            
if (options.addPromptClass)
                
prompt.addClass(options.addPromptClass);

            
// Add custom prompt class defined in element
            
var requiredOverride = field.attr('data-required-class');
            if (
requiredOverride !== undefined) {
                
prompt.addClass(requiredOverride);
            } else {
                if (
options.prettySelect) {
                    if ($(
'#' + field.attr('id')).next().is('select')) {
                        var 
prettyOverrideClass = $('#' + field.attr('id').substr(options.usePrefix.length).substring(options.useSuffix.length)).attr('data-required-class');
                        if (
prettyOverrideClass !== undefined) {
                            
prompt.addClass(prettyOverrideClass);
                        }
                    }
                }
            }

            
prompt.css({
                
"opacity": 0
            
});
            if (
positionType === 'inline') {
                
prompt.addClass("inline");
                if (
typeof field.attr('data-prompt-target') !== 'undefined' && $('#' + field.attr('data-prompt-target')).length > 0) {
                    
prompt.appendTo($('#' + field.attr('data-prompt-target')));
                } else {
                    
field.after(prompt);
                }
            } else {
                
field.before(prompt);
            }

            var 
pos = methods._calculatePosition(field, prompt, options);
            
prompt.css({
                
'position': positionType === 'inline' ? 'relative' : 'absolute',
                
"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 (field, prompt, promptText, type, ajaxed, options, noAnimation) {

            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(field, prompt, options);
                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, .validationEngineContainer').attr('id');
            var 
className = methods._getClassName(field.attr("id")) + "formError";
            var 
match = $("." + methods._escapeExpression(className) + '.parentForm' + methods._getClassName(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 (field, promptElmt, options) {

            var 
promptTopPosition, promptleftPosition, marginTopSize;
            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 - 27;
                    
promptTopPosition += fieldTop;
                    break;

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

                case 
"centerRight":
                    
promptTopPosition = fieldTop + 4;
                    
marginTopSize = 0;
                    
promptleftPosition = fieldLeft + 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 - 27;
                    
promptTopPosition = fieldTop + field.height() + 5;
                    
marginTopSize = 0;
                    break;
                case 
"inline":
                    
promptleftPosition = 0;
                    
promptTopPosition = 0;
                    
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 (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(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, "_");
        },
        
/**
         * Escape special character for jQuery selector
         * http://totaldev.com/content/escaping-characters-get-valid-jquery-id
         * @param {String} selector
         */
        
_jqSelector: function (str) {
            return 
str.replace(/([;&,.+*~':"!^#$%@[]()=>|])/g, '\$1');
        },
        /**
         * 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 (field, rules, i, options) {
            var idx, dependingField;

            for (idx = (i + 1); idx < rules.length; idx++) {
                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
                 
* Indicate this special use by setting the last parameter to true so we only validate the dependingField on chackboxes and radio buttons (#462)
                 
*/
                if (
dependingField.length && methods._required(dependingField, ["required"], 0, options, true) == 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"], 0, options);
                }
            }
        },

        
_submitButtonClick: function (event) {
            var 
button = $(this);
            var 
form = button.closest('form, .validationEngineContainer');
            
form.data("jqv_submitButton", button.attr("id"));
        }
    };

    
/**
     * 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(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 = {fieldIdCounter: 0, defaults: {

        
// Name of the event triggering field validation
        
validationEventTrigger: "blur",
        
// Automatically scroll viewport to the first error
        
scroll: true,
        
// Focus on the first input
        
focusFirstField: true,
        
// Show prompts, set to false to disable prompts
        
showPrompts: true,
        
// Should we attempt to validate non-visible input fields contained in the form? (Useful in cases of tabbed containers, e.g. jQuery-UI tabs)
        
validateNonVisibleFields: false,
        
// Opening box position, possible locations are: topLeft,
        // topRight, bottomLeft, centerRight, bottomRight, inline
        // inline gets inserted after the validated field or into an element specified in data-prompt-target
        
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,
        
// The url to send the submit ajax validation (default to action)
        
ajaxFormValidationURL: false,
        
// 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
        
onValidationComplete: false,

        
// Used when you have a form fields too close and the errors messages are on top of other disturbing viewing messages
        
doNotShowAllErrosOnSubmit: false,
        
// Object where you store custom messages to override the default error messages
        
custom_error_messages: {},
        
// true if you want to validate the input fields on blur event
        
binded: true,
        
// set to true, when the prompt arrow needs to be displayed
        
showArrow: true,
        
// set to false, determines if the prompt arrow should be displayed when validating
        // checkboxes and radio buttons
        
showArrowOnRadioAndCheckbox: false,
        
// did one of the validation fail ? kept global to stop further ajax validations
        
isError: false,
        
// Limit how many displayed errors a field can have
        
maxErrorsPerField: 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: {},
        
// Auto update prompt position after window resize
        
autoPositionUpdate: false,

        
InvalidFields: [],
        
onFieldSuccess: false,
        
onFieldFailure: false,
        
onSuccess: false,
        
onFailure: false,
        
validateAttribute: "class",
        
addSuccessCssClassToField: "",
        
addFailureCssClassToField: "",

        
// Auto-hide prompt
        
autoHidePrompt: false,
        
// Delay before auto-hide
        
autoHideDelay: 10000,
        
// Fade out duration while hiding the validations
        
fadeDuration: 0.3,
        
// Use Prettify select library
        
prettySelect: false,
        
// Add css class on prompt
        
addPromptClass: "",
        
// Custom ID uses prefix
        
usePrefix: "",
        
// Custom ID uses suffix
        
useSuffix: "",
        
// Only show one message per error prompt
        
showOneMessage: false
    
}};
    $(function () {
        $.
validationEngine.defaults.promptPosition = methods.isRTL() ? 'topLeft' : "topRight"
    
});
})(
jQuery);
?>
Онлайн: 2
Реклама