PageSourceSearch

https://www.pigbcs.com/DesktopModules/DNNGo_xBlog/Resource/js/jquery.validationEngine.js?cdv=204

js pigbcs.com collected 2026-10-06 20:40:18 UTC 92,695 bytes, 2,086 lines download raw bytes

1/*
2* Inline Form Validation Engine 2.6.2, jQuery plugin
3*
4* Copyright(c) 2010, Cedric Dugas
5* http://www.position-absolute.com
6*
7* 2.0 Rewrite by Olivier Refalo
8* http://www.crionics.com
9*
10* Form validation engine allowing custom regex rules to be added.
11* Licensed under the MIT License
12*/
13(function ($) {
14
15    "use strict";
16
17    var methods = {
18
19        /**
20        * Kind of the constructor, called before any action
21        * @param {Map} user options
22        */
23        init: function (options) {
24
25            var form = this;
26            if (!form.data('jqv') || form.data('jqv') == null) {
27                options = methods._saveOptions(form, options);
28                // bind all formError elements to close on click
29                $(document).on("click", ".formError", function () {
30                    $(this).fadeOut(150, function () {
31                        // remove prompt once invisible
32                        $(this).parent('.formErrorOuter').remove();
33                        $(this).remove();
34                    });
35                });
36            }
37            return this;
38        },
39        /**
40        * Attachs jQuery.validationEngine to form.submit and field.blur events
41        * Takes an optional params: a list of options
42        * ie. jQuery("#formID1").validationEngine('attach', {promptPosition : "centerRight"});
43        */
44        attach: function (userOptions) {
45
46            var form = this;
47            var options;
48
49            if (userOptions)
50                options = methods._saveOptions(form, userOptions);
51            else
52                options = form.data('jqv');
53
54            options.validateAttribute = (form.find("[data-validation-engine*=validate]").length) ? "data-validation-engine" : "class";
55            if (options.binded) {
56
57                // delegate fields
58                form.on(options.validationEventTrigger, "[" + options.validateAttribute + "*=validate]:not([type=checkbox]):not([type=radio]):not(.datepicker)", methods._onFieldEvent);
59                form.on("click", "[" + options.validateAttribute + "*=validate][type=checkbox],[" + options.validateAttribute + "*=validate][type=radio]", methods._onFieldEvent);
60                form.on(options.validationEventTrigger, "[" + options.validateAttribute + "*=validate][class*=datepicker]", { "delay": 300 }, methods._onFieldEvent);
61            }
62            if (options.autoPositionUpdate) {
63                $(window).bind("resize", {
64                    "noAnimation": true,
65                    "formElem": form
66                }, methods.updatePromptsPosition);
67            }
68            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);
69            form.removeData('jqv_submitButton');
70
71            // bind form.submit
72            form.on("submit", methods._onSubmitEvent);
73            return this;
74        },
75        /**
76        * Unregisters any bindings that may point to jQuery.validaitonEngine
77        */
78        detach: function () {
79
80            var form = this;
81            var options = form.data('jqv');
82
83            // unbind fields
84            form.find("[" + options.validateAttribute + "*=validate]").not("[type=checkbox]").off(options.validationEventTrigger, methods._onFieldEvent);
85            form.find("[" + options.validateAttribute + "*=validate][type=checkbox],[class*=validate][type=radio]").off("click", methods._onFieldEvent);
86
87            // unbind form.submit
88            form.off("submit", methods._onSubmitEvent);
89            form.removeData('jqv');
90
91            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);
92            form.removeData('jqv_submitButton');
93
94            if (options.autoPositionUpdate)
95                $(window).off("resize", methods.updatePromptsPosition);
96
97            return this;
98        },
99        /**
100        * Validates either a form or a list of fields, shows prompts accordingly.
101        * Note: There is no ajax form validation with this method, only field ajax validation are evaluated
102        *
103        * @return true if the form validates, false if it fails
104        */
105        validate: function () {
106
107            var element = $(this);
108            var valid = null;
109
110            if (element.is("form") || element.hasClass("validationEngineContainer")) {
111
112                if (element.hasClass('validating')) {
113
114                    // form is already validating.
115                    // Should abort old validation and start new one. I don't know how to implement it.
116                    return false;
117                } else {
118                    element.addClass('validating');
119                    var options = element.data('jqv');
120                    var valid = methods._validateFields(this);
121
122                    // If the form doesn't validate, clear the 'validating' class before the user has a chance to submit again
123                    setTimeout(function () {
124                        element.removeClass('validating');
125                    }, 100);
126                    if (valid && options.onSuccess) {
127                        options.onSuccess();
128                    } else if (!valid && options.onFailure) {
129                        options.onFailure();
130                    }
131                }
132            } else if (element.is('form') || element.hasClass('validationEngineContainer')) {
133                element.removeClass('validating');
134            } else {
135                // field validation
136                var form = element.closest('form, .validationEngineContainer'),
137					options = (form.data('jqv')) ? form.data('jqv') : $.validationEngine.defaults,
138					valid = methods._validateField(element, options);
139                if (valid && options.onFieldSuccess)
140                    options.onFieldSuccess();
141                else if (options.onFieldFailure && options.InvalidFields.length > 0) {
142                    options.onFieldFailure();
143                }
144            }
145            if (options.onValidationComplete) {
146                // !! ensures that an undefined return is interpreted as return false but allows a onValidationComplete() to possibly return true and have form continue processing
147                return !!options.onValidationComplete(form, valid);
148            }
149            return valid;
150        },
151        /**
152        *  Redraw prompts position, useful when you change the DOM state when validating
153        */
154        updatePromptsPosition: function (event) {
155
156            if (event && this == window) {
157                var form = event.data.formElem;
158                var noAnimation = event.data.noAnimation;
159            }
160            else
161                var form = $(this.closest('form, .validationEngineContainer'));
162
163            var options = form.data('jqv');
164            // No option, take default one
165            form.find('[' + options.validateAttribute + '*=validate]').not(":disabled").each(function () {
166                var field = $(this);
167                if (options.prettySelect && field.is(":hidden"))
168                    field = form.find("#" + options.usePrefix + field.attr('id') + options.useSuffix);
169                var prompt = methods._getPrompt(field);
170                var promptText = $(prompt).find(".formErrorContent").html();
171
172                if (prompt)
173                    methods._updatePrompt(field, $(prompt), promptText, undefined, false, options, noAnimation);
174            });
175            return this;
176        },
177        /**
178        * Displays a prompt on a element.
179        * Note that the element needs an id!
180        *
181        * @param {String} promptText html text to display type
182        * @param {String} type the type of bubble: 'pass' (green), 'load' (black) anything else (red)
183        * @param {String} possible values topLeft, topRight, bottomLeft, centerRight, bottomRight
184        */
185        showPrompt: function (promptText, type, promptPosition, showArrow) {
186            var form = this.closest('form, .validationEngineContainer');
187            var options = form.data('jqv');
188            // No option, take default one
189            if (!options)
190                options = methods._saveOptions(this, options);
191            if (promptPosition)
192                options.promptPosition = promptPosition;
193            options.showArrow = showArrow == true;
194
195            methods._showPrompt(this, promptText, type, false, options);
196            return this;
197        },
198        /**
199        * Closes form error prompts, CAN be invidual
200        */
201        hide: function () {
202            var form = $(this).closest('form, .validationEngineContainer');
203            var options = form.data('jqv');
204            var fadeDuration = (options && options.fadeDuration) ? options.fadeDuration : 0.3;
205            var closingtag;
206
207            if ($(this).is("form") || $(this).hasClass("validationEngineContainer")) {
208                closingtag = "parentForm" + methods._getClassName($(this).attr("id"));
209            } else {
210                closingtag = methods._getClassName($(this).attr("id")) + "formError";
211            }
212            $('.' + closingtag).fadeTo(fadeDuration, 0.3, function () {
213                $(this).parent('.formErrorOuter').remove();
214                $(this).remove();
215            });
216            return this;
217        },
218        /**
219        * Closes all error prompts on the page
220        */
221        hideAll: function () {
222
223            var form = this;
224            var options = form.data('jqv');
225            var duration = options ? options.fadeDuration : 300;
226            $('.formError').fadeTo(duration, 300, function () {
227                $(this).parent('.formErrorOuter').remove();
228                $(this).remove();
229            });
230            return this;
231        },
232        /**
233        * Typically called when user exists a field using tab or a mouse click, triggers a field
234        * validation
235        */
236        _onFieldEvent: function (event) {
237            var field = $(this);
238            var form = field.closest('form, .validationEngineContainer');
239            var options = form.data('jqv');
240            options.eventTrigger = "field";
241            // validate the current field
242            window.setTimeout(function () {
243                methods._validateField(field, options);
244                if (options.InvalidFields.length == 0 && options.onFieldSuccess) {
245                    options.onFieldSuccess();
246                } else if (options.InvalidFields.length > 0 && options.onFieldFailure) {
247                    options.onFieldFailure();
248                }
249            }, (event.data) ? event.data.delay : 0);
250
251        },
252        /**
253        * Called when the form is submited, shows prompts accordingly
254        *
255        * @param {jqObject}
256        *            form
257        * @return false if form submission needs to be cancelled
258        */
259        _onSubmitEvent: function () {
260            var form = $(this);
261            var options = form.data('jqv');
262
263            //check if it is trigger from skipped button
264            if (form.data("jqv_submitButton")) {
265                var submitButton = $("#" + form.data("jqv_submitButton"));
266                if (submitButton) {
267                    if (submitButton.length > 0) {
268                        if (submitButton.hasClass("validate-skip") || submitButton.attr("data-validation-engine-skip") == "true")
269                            return true;
270                    }
271                }
272            }
273
274            options.eventTrigger = "submit";
275
276            // validate each field 
277            // (- skip field ajax validation, not necessary IF we will perform an ajax form validation)
278            var r = methods._validateFields(form);
279
280            if (r && options.ajaxFormValidation) {
281                methods._validateFormWithAjax(form, options);
282                // cancel form auto-submission - process with async call onAjaxFormComplete
283                return false;
284            }
285
286            if (options.onValidationComplete) {
287                // !! ensures that an undefined return is interpreted as return false but allows a onValidationComplete() to possibly return true and have form continue processing
288                return !!options.onValidationComplete(form, r);
289            }
290            return r;
291        },
292        /**
293        * Return true if the ajax field validations passed so far
294        * @param {Object} options
295        * @return true, is all ajax validation passed so far (remember aja
295x is async)
296        */
297        _checkAjaxStatus: function (options) {
298            var status = true;
299            $.each(options.ajaxValidCache, function (key, value) {
300                if (!value) {
301                    status = false;
302                    // break the each
303                    return false;
304                }
305            });
306            return status;
307        },
308
309        /**
310        * Return true if the ajax field is validated
311        * @param {String} fieldid
312        * @param {Object} options
313        * @return true, if validation passed, false if false or doesn't exist
314        */
315        _checkAjaxFieldStatus: function (fieldid, options) {
316            return options.ajaxValidCache[fieldid] == true;
317        },
318        /**
319        * Validates form fields, shows prompts accordingly
320        *
321        * @param {jqObject}
322        *            form
323        * @param {skipAjaxFieldValidation}
324        *            boolean - when set to true, ajax field validation is skipped, typically used when the submit button is clicked
325        *
326        * @return true if form is valid, false if not, undefined if ajax form validation is done
327        */
328        _validateFields: function (form) {
329            var options = form.data('jqv');
330
331            // this variable is set to true if an error is found
332            var errorFound = false;
333
334            // Trigger hook, start validation
335            form.trigger("jqv.form.validating");
336            // first, evaluate status of non ajax fields
337            var first_err = null;
338            form.find('[' + options.validateAttribute + '*=validate]').not(":disabled").each(function () {
339                var field = $(this);
340                var names = [];
341                if ($.inArray(field.attr('name'), names) < 0) {
342                    errorFound |= methods._validateField(field, options);
343                    if (errorFound && first_err == null)
344                        if (field.is(":hidden") && options.prettySelect)
345                            first_err = field = form.find("#" + options.usePrefix + methods._jqSelector(field.attr('id')) + options.useSuffix);
346                        else {
347
348                            //Check if we need to adjust what element to show the prompt on
349                            //and and such scroll to instead
350                            if (field.data('jqv-prompt-at') instanceof jQuery) {
351                                field = field.data('jqv-prompt-at');
352                            } else if (field.data('jqv-prompt-at')) {
353                                field = $(field.data('jqv-prompt-at'));
354                            }
355                            first_err = field;
356                        }
357                    if (options.doNotShowAllErrosOnSubmit)
358                        return false;
359                    names.push(field.attr('name'));
360
361                    //if option set, stop checking validation rules after one error is found
362                    if (options.showOneMessage == true && errorFound) {
363                        return false;
364                    }
365                }
366            });
367
368            // second, check to see if all ajax calls completed ok
369            // errorFound |= !methods._checkAjaxStatus(options);
370
371            // third, check status and scroll the container accordingly
372            form.trigger("jqv.form.result", [errorFound]);
373
374            if (errorFound) {
375                if (options.scroll) {
376                    var destination = first_err.offset().top;
377                    var fixleft = first_err.offset().left;
378
379                    //prompt positioning adjustment support. Usage: positionType:Xshift,Yshift (for ex.: bottomLeft:+20 or bottomLeft:-20,+10)
380                    var positionType = options.promptPosition;
381                    if (typeof (positionType) == 'string' && positionType.indexOf(":") != -1)
382                        positionType = positionType.substring(0, positionType.indexOf(":"));
383
384                    if (positionType != "bottomRight" && positionType != "bottomLeft") {
385                        var prompt_err = methods._getPrompt(first_err);
386                        if (prompt_err) {
387                            destination = prompt_err.offset().top;
388                        }
389                    }
390
391                    // Offset the amount the page scrolls by an amount in px to accomodate fixed elements at top of page
392                    if (options.scrollOffset) {
393                        destination -= options.scrollOffset;
394                    }
395
396                    // get the position of the first error, there should be at least one, no need to check this
397                    //var destination = form.find(".formError:not('.greenPopup'):first").offset().top;
398                    if (options.isOverflown) {
399                        var overflowDIV = $(options.overflownDIV);
400                        if (!overflowDIV.length) return false;
401                        var scrollContainerScroll = overflowDIV.scrollTop();
402                        var scrollContainerPos = -parseInt(overflowDIV.offset().top);
403
404                        destination += scrollContainerScroll + scrollContainerPos - 5;
405                        var scrollContainer = $(options.overflownDIV + ":not(:animated)");
406
407                        scrollContainer.animate({ scrollTop: destination }, 1100, function () {
408                            if (options.focusFirstField) first_err.focus();
409                        });
410
411                    } else {
412                        $("html, body").animate({
413                            scrollTop: destination
414                        }, 1100, function () {
415                            if (options.focusFirstField) first_err.focus();
416                        });
417                        $("html, body").animate({ scrollLeft: fixleft }, 1100)
418                    }
419
420                } else if (options.focusFirstField)
421                    first_err.focus();
422                return false;
423            }
424            return true;
425        },
426        /**
427        * This method is called to perform an ajax form validation.
428        * During this process all the (field, value) pairs are sent to the server which returns a list of invalid fields or true
429        *
430        * @param {jqObject} form
431        * @param {Map} options
432        */
433        _validateFormWithAjax: function (form, options) {
434
435            var data = form.serialize();
436            var type = (options.ajaxFormValidationMethod) ? options.ajaxFormValidationMethod : "GET";
437            var url = (options.ajaxFormValidationURL) ? options.ajaxFormValidationURL : form.attr("action");
438            var dataType = (options.dataType) ? options.dataType : "json";
439            $.ajax({
440                type: type,
441                url: url,
442                cache: false,
443                dataType: dataType,
444                data: data,
445                form: form,
446                methods: methods,
447                options: options,
448                beforeSend: function () {
449                    return options.onBeforeAjaxFormValidation(form, options);
450                },
451                error: function (data, transport) {
452                    methods._ajaxError(data, transport);
453                },
454                success: function (json) {
455                    if ((dataType == "json") && (json !== true)) {
456                        // getting to this case doesn't necessary means that the form is invalid
457                        // the server may return green or closing prompt actions
458                        // this flag helps figuring it out
459                        var errorInForm = false;
460                        for (var i = 0; i < json.length; i++) {
461                            var value = json[i];
462
463                            var errorFieldId = value[0];
464                            var errorField = $($("#" + errorFieldId)[0]);
465
466                            // make sure we found the element
467                            if (errorField.length == 1) {
468
469                                // promptText or selector
470                                var msg = value[2];
471                                // if the field is valid
472                                if (value[1] == true) {
473
474                                    if (msg == "" || !msg) {
475                                        // if for some reason, status==true and error="", just close the prompt
476                                        methods._closePrompt(errorField);
477                                    } else {
478                                        // the field is valid, but we are displaying a green prompt
479                                        if (options.allrules[msg]) {
480                                            var txt = options.allrules[msg].alertTextOk;
481                                            if (txt)
482                                                msg = txt;
483                                        }
484                                        if (options.showPrompts) methods._showPrompt(errorField, msg, "pass", false, options, true);
485                                    }
486                                } else {
487                                    // the field is invalid, show the red error prompt
488                                    errorInForm |= true;
489                                    if (options.allrules[msg]) {
490                                        var txt = options.allrules[msg].alertText;
491                                        if (txt)
492                                            msg = txt;
493                                    }
494                                    if (options.showPrompts) methods._showPrompt(errorField, msg, "", false, options, true);
495                                }
496                            }
497                        }
498                        options.onAjaxFormComplete(!errorInForm, form, json, options);
499                    } else
500                        options.onAjaxFormComplete(true, form, json, options);
501
502                }
503            });
504
505        },
506        /**
507        * Validates field, shows prompts accordingly
508        *
509        * @param {jqObject}
510        *            field
511        * @param {Array[String]}
512        *            field's validation rules
513        * @param {Map}
514        *            user options
515        * @return false if field is valid (It is inversed for *fields*, it return false on validate and true on errors.)
516        */
517        _validateField: function (field, options, skipAjaxValidation) {
518            if (!field.attr("id")) {
519                field.attr("id", "form-validation-field-" + $.validationEngine.fieldIdCounter);
520                ++$.validationEngine.fieldIdCounter;
521            }
522
523            if (!options.validateNonVisibleFields && (field.is(":hidden") && !options.prettySelect || field.parent().is(":hidden")))
524                return false;
525
526            var rulesParsing = field.attr(options.validateAttribute);
527            var getRules = /validate\[(.*)\]/.exec(rulesParsing);
528
529            if (!getRules)
530                return false;
531            var str = getRules[1];
532            var rules = str.split(/\[|,|\]/);
533
534            // true if we ran the ajax validation, tells the logic to stop messing with prompts
535            var isAjaxValidator = false;
536            var fieldName = field.attr("name");
537            var promptText = "";
538            var promptType = "";
539            var required = false;
540            var limitErrors = false;
541            options.isError = false;
542            options.showArrow = true;
543
544            // If the programmer wants to limit the amount of error messages per field,
545            if (options.maxErrorsPerField > 0) {
546                limitErrors = true;
547            }
548
549            var form = $(field.closest("form, .validationEngineContainer"));
550            // Fix for adding spaces in the rules
551            for (var i = 0; i < rules.length; i++) {
552                rules[i] = rules[i].replace(" ", "");
553                // Remove any parsing errors
554                if (rules[i] === '') {
555                    delete rules[i];
556                }
557            }
558
559            for (var i = 0, field_errors = 0; i < rules.length; i++) {
560
561                // If we are limiting errors, and have hit the max, break
562                if (limitErrors && field_errors >= options.maxErrorsPerField) {
563                    // If we haven't hit a required yet, check to see if there is one in the validation rules for this
564                    // field and that it's index is greater or equal to our current index
565                    if (!required) {
566                        var have_required = $.inArray('required', rules);
567                        required = (have_required != -1 && have_required >= i);
568                    }
569                    break;
570                }
571
572
573                var errorMsg = undefined;
574                switch (rules[i]) {
575
576                    case "required":
577                        required = true;
578                        errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._required);
579                        break;
580                    case "custom":
581                        errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._custom);
582                        break;
583                    case "groupRequired":
584                        // Check is its the first of group, if not, reload validation with first field
585                        // AND continue normal validation on present field
586                        var classGroup = "[" + options.validateAttribute + "*=" + rules[i + 1] + "]";
587                        var firstOfGroup = form.find(classGroup).eq(0);
588                        if (firstOfGroup[0] != field[0]) {
589
590                            methods._validateField(firstOfGroup, options, skipAjaxValidation);
591                            options.showArrow = true;
592
593                        }
594                        errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._groupRequired);
595                        if (errorMsg) required = true;
596                        options.showArrow = false;
597                        break;
598                    case "ajax":
599                        // AJAX defaults to returning it's loading message
600                        errorMsg = methods._ajax(field, rules, i, options);
601                        if (errorMsg) {
602                            promptType = "load";
603                        }
604                        break;
605                    case "minSize":
606                        errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._minSize);
607                        break;
608                    case "maxSize":
609                        errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._maxSize);
610                        break;
611                    case "min":
612                        errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._min);
613                        break;
614                    case "max":
615                        errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._max);
616                        break;
617                    case "past":
618                        errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._past);
619                        break;
620                    case "future":
621                        errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._future);
622                        break;
623                    case "dateRange":
624                        var classGroup = "[" + options.validateAttribute + "*=" 
624+ rules[i + 1] + "]";
625                        options.firstOfGroup = form.find(classGroup).eq(0);
626                        options.secondOfGroup = form.find(classGroup).eq(1);
627
628                        //if one entry out of the pair has value then proceed to run through validation
629                        if (options.firstOfGroup[0].value || options.secondOfGroup[0].value) {
630                            errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._dateRange);
631                        }
632                        if (errorMsg) required = true;
633                        options.showArrow = false;
634                        break;
635
636                    case "dateTimeRange":
637                        var classGroup = "[" + options.validateAttribute + "*=" + rules[i + 1] + "]";
638                        options.firstOfGroup = form.find(classGroup).eq(0);
639                        options.secondOfGroup = form.find(classGroup).eq(1);
640
641                        //if one entry out of the pair has value then proceed to run through validation
642                        if (options.firstOfGroup[0].value || options.secondOfGroup[0].value) {
643                            errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._dateTimeRange);
644                        }
645                        if (errorMsg) required = true;
646                        options.showArrow = false;
647                        break;
648                    case "maxCheckbox":
649                        field = $(form.find("input[name='" + fieldName + "']"));
650                        errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._maxCheckbox);
651                        break;
652                    case "minCheckbox":
653                        field = $(form.find("input[name='" + fieldName + "']"));
654                        errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._minCheckbox);
655                        break;
656                    case "equals":
657                        errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._equals);
658                        break;
659                    case "funcCall":
660                        errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._funcCall);
661                        break;
662                    case "creditCard":
663                        errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._creditCard);
664                        break;
665                    case "condRequired":
666                        errorMsg = methods._getErrorMessage(form, field, rules[i], rules, i, options, methods._condRequired);
667                        if (errorMsg !== undefined) {
668                            required = true;
669                        }
670                        break;
671
672                    default:
673                }
674
675                var end_validation = false;
676
677                // If we were passed back an message object, check what the status was to determine what to do
678                if (typeof errorMsg == "object") {
679                    switch (errorMsg.status) {
680                        case "_break":
681                            end_validation = true;
682                            break;
683                        // If we have an error message, set errorMsg to the error message       
684                        case "_error":
685                            errorMsg = errorMsg.message;
686                            break;
687                        // If we want to throw an error, but not show a prompt, return early with true       
688                        case "_error_no_prompt":
689                            return true;
690                            break;
691                        // Anything else we continue on       
692                        default:
693                            break;
694                    }
695                }
696
697                // If it has been specified that validation should end now, break
698                if (end_validation) {
699                    break;
700                }
701
702                // If we have a string, that means that we have an error, so add it to the error message.
703                if (typeof errorMsg == 'string') {
704                    promptText += errorMsg + "<br/>";
705                    options.isError = true;
706                    field_errors++;
707                }
708            }
709            // If the rules required is not added, an empty field is not val
709idated
710            if (!required && !(field.val()) && field.val().length < 1) options.isError = false;
711
712            // Hack for radio/checkbox group button, the validation go into the
713            // first radio/checkbox of the group
714            var fieldType = field.prop("type");
715            var positionType = field.data("promptPosition") || options.promptPosition;
716
717            if ((fieldType == "radio" || fieldType == "checkbox") && form.find("input[name='" + fieldName + "']").size() > 1) {
718                if (positionType === 'inline') {
719                    field = $(form.find("input[name='" + fieldName + "'][type!=hidden]:last"));
720                } else {
721                    field = $(form.find("input[name='" + fieldName + "'][type!=hidden]:first"));
722                }
723                options.showArrow = false;
724            }
725
726            if (field.is(":hidden") && options.prettySelect) {
727                field = form.find("#" + options.usePrefix + methods._jqSelector(field.attr('id')) + options.useSuffix);
728            }
729
730            if (options.isError && options.showPrompts) {
731                methods._showPrompt(field, promptText, promptType, false, options);
732            } else {
733                if (!isAjaxValidator) methods._closePrompt(field);
734            }
735
736            if (!isAjaxValidator) {
737                field.trigger("jqv.field.result", [field, options.isError, promptText]);
738            }
739
740            /* Record error */
741            var errindex = $.inArray(field[0], options.InvalidFields);
742            if (errindex == -1) {
743                if (options.isError)
744                    options.InvalidFields.push(field[0]);
745            } else if (!options.isError) {
746                options.InvalidFields.splice(errindex, 1);
747            }
748
749            methods._handleStatusCssClasses(field, options);
750
751            /* run callback function for each field */
752            if (options.isError && options.onFieldFailure)
753                options.onFieldFailure(field);
754
755            if (!options.isError && options.onFieldSuccess)
756                options.onFieldSuccess(field);
757
758            return options.isError;
759        },
760        /**
761        * Handling css classes of fields indicating result of validation 
762        *
763        * @param {jqObject}
764        *            field
765        * @param {Array[String]}
766        *            field's validation rules            
767        * @private
768        */
769        _handleStatusCssClasses: function (field, options) {
770            /* remove all classes */
771            if (options.addSuccessCssClassToField)
772                field.removeClass(options.addSuccessCssClassToField);
773
774            if (options.addFailureCssClassToField)
775                field.removeClass(options.addFailureCssClassToField);
776
777            /* Add classes */
778            if (options.addSuccessCssClassToField && !options.isError)
779                field.addClass(options.addSuccessCssClassToField);
780
781            if (options.addFailureCssClassToField && options.isError)
782                field.addClass(options.addFailureCssClassToField);
783        },
784
785        /********************
786        * _getErrorMessage
787        *
788        * @param form
789        * @param field
790        * @param rule
791        * @param rules
792        * @param i
793        * @param options
794        * @param originalValidationMethod
795        * @return {*}
796        * @private
797        */
798        _getErrorMessage: function (form, field, rule, rules, i, options, originalValidationMethod) {
799            // If we are using the custon validation type, build the index for the rule.
800            // Otherwise if we are doing a function call, make the call and return the object
801            // that is passed back.
802            var rule_index = jQuery.inArray(rule, rules);
803            if (rule === "custom" || rule === "funcCall") {
804                var custom_validation_type = rules[rule_index + 1];
805                rule = rule + "[" + custom_validation_type + "]";
806                // Delete the rule from the rules array so that it doesn't try to call the
807                // same rule over again
808                delete (rules[rule_index]);
809            }
810            // Change the rule to the composite rule, if it was different from the original
811            var alteredRule = rule;
812
813
814            var element_classes = (field.attr("data-validation-engine")) ? field.attr("data-validation-engine") : field.attr("class");
815            var element_classes_array = element_classes.split(" ");
816
817            // Call the original validation method. If we are dealing with dates or checkboxes, also pass the form
818            var errorMsg;
819            if (rule == "future" || rule == "past" || rule == "maxCheckbox" || rule == "minCheckbox") {
820                errorMsg = originalValidationMethod(form, field, rules, i, options);
821            } else {
822                errorMsg = originalValidationMethod(field, rules, i, options);
823            }
824
825            // If the original validation method returned an error and we have a custom error message,
826            // return the custom message instead. Otherwise return the original error message.
827            if (errorMsg != undefined) {
828                var custom_message = methods._getCustomErrorMessage($(field), element_classes_array, alteredRule, options);
829                if (custom_message) errorMsg = custom_message;
830            }
831            return errorMsg;
832
833        },
834        _getCustomErrorMessage: function (field, classes, rule, options) {
835            var custom_message = false;
836            var validityProp = /^custom\[.*\]$/.test(rule) ? methods._validityProp["custom"] : methods._validityProp[rule];
837            // If there is a validityProp for this rule, check to see if the field has an attribute for it
838            if (validityProp != undefined) {
839                custom_message = field.attr("data-errormessage-" + validityProp);
840                // If there was an error message for it, return the message
841                if (custom_message != undefined)
842                    return custom_message;
843            }
844            custom_message = field.attr("data-errormessage");
845            // If there is an inline custom error message, return it
846            if (custom_message != undefined)
847                return custom_message;
848            var id = '#' + field.attr("id");
849            // If we have custom messages for the element's id, get the message for the rule from the id.
850            // Otherwise, if we have custom messages for the element's classes, use the first class message we find instead.
851            if (typeof options.custom_error_messages[id] != "undefined" &&
852				typeof options.custom_error_messages[id][rule] != "undefined") {
853                custom_message = options.custom_error_messages[id][rule]['message'];
854            } else if (classes.length > 0) {
855                for (var i = 0; i < classes.length && classes.length > 0; i++) {
856                    var element_class = "." + classes[i];
857                    if (typeof options.custom_error_messages[element_class] != "undefined" &&
858						typeof options.custom_error_messages[element_class][rule] != "undefined") {
859                        custom_message = options.custom_error_messages[element_class][rule]['message'];
860                        break;
861                    }
862                }
863            }
864            if (!custom_message &&
865				typeof options.custom_error_messages[rule] != "undefined" &&
866				typeof options.custom_error_messages[rule]['message'] != "undefined") {
867                custom_message = options.custom_error_messages[rule]['message'];
868            }
869            return custom_message;
870        },
871        _validityProp: {
872            "required": "value-missing",
873            "custom": "custom-error",
874            "groupRequired": "value-missing",
875            "ajax": "custom-error",
876            "minSize": "range-underflow",
877            "maxSize": "range-overflow",
878            "min": "range-underflow",
879            "max": "range-overflow",
880            "past": "type-mismatch",
881            "future": "type-mismatch",
882            "dateRange": "type-mismatch",
883            "dateTimeRange": "type-mismatch",
884            "maxCheckbox": "range-overflow",
885            "minCheckbox": "range-underflow",
886            "equals": "pattern-mismatch",
887            "funcCall": "custom-error",
888            "creditCard": "pattern-mismatch",
889            "condRequired": "value-missing"
890        },
891        /**
892        * Required validation
893        *
894        * @param {jqObject} field
895        * @param {Array[String]} rules
896        * @param {int} i rules index
897        * @param {Map}
898        *            user options
899        * @param {bool} condRequired flag when method is used for internal purpose in condRequired check
900        * @return an error string if validation failed
901        */
902        _required: function (field, rules, i, options, condRequired) {
903            switch (field.prop("type")) {
904                case "text":
905                case "password":
906                case "textarea":
907                case "file":
908                case "select-one":
909                case "select-multiple":
910                default:
911                    var field_val = $.trim(field.val());
912                    var dv_placeholder = $.trim(field.attr("data-validation-placeholder"));
913                    var placeholder = $.trim(field.attr("placeholder"));
914                    if (
915						   (!field_val)
916						|| (dv_placeholder && field_val == dv_placeholder)
917						|| (placeholder && field_val == placeholder)
918					) {
919                        return options.allrules[rules[i]].alertText;
920                    }
921                    break;
922                case "radio":
923                case "checkbox":
924                    // new validation style to only check dependent field
925                    if (condRequired) {
926                        if (!field.attr('checked')) {
927                            return options.allrules[rules[i]].alertTextCheckboxMultiple;
928                        }
929                        break;
930                    }
931                    // old validation style
932                    var form = field.closest("form, .validationEngineContainer");
933                    var name = field.attr("name");
934                    if (form.find("input[name='" + name + "']:checked").size() == 0) {
935                        if (form.find("input[name='" + name + "']:visible").size() == 1)
936                            return options.allrules[rules[i]].alertTextCheckboxe;
937                        else
938                            return options.allrules[rules[i]].alertTextCheckboxMultiple;
939                    }
940                    break;
941            }
942        },
943        /**
944        * Validate that 1 from the group field is required
945        *
946        * @param {jqObject} field
947        * @param {Array[String]} rules
948        * @param {int} i rules index
949        * @param {Map}
950        *            user options
951        * @return an error string if validation failed
952        */
953        _groupRequired: function (field, rules, i, options) {
954            var classGroup = "[" + options.validateAttribute + "*=" 
954+ rules[i + 1] + "]";
955            var isValid = false;
956            // Check all fields from the group
957            field.closest("form, .validationEngineContainer").find(classGroup).each(function () {
958                if (!methods._required($(this), rules, i, options)) {
959                    isValid = true;
960                    return false;
961                }
962            });
963
964            if (!isValid) {
965                return options.allrules[rules[i]].alertText;
966            }
967        },
968        /**
969        * Validate rules
970        *
971        * @param {jqObject} field
972        * @param {Array[String]} rules
973        * @param {int} i rules index
974        * @param {Map}
975        *            user options
976        * @return an error string if validation failed
977        */
978        _custom: function (field, rules, i, options) {
979            var customRule = rules[i + 1];
980            var rule = options.allrules[customRule];
981            var fn;
982            if (!rule) {
983                alert("jqv:custom rule not found - " + customRule);
984                return;
985            }
986
987            if (rule["regex"]) {
988                var ex = rule.regex;
989                if (!ex) {
990                    alert("jqv:custom regex not found - " + customRule);
991                    return;
992                }
993                var pattern = new RegExp(ex);
994
995                if (!pattern.test(field.val())) return options.allrules[customRule].alertText;
996
997            } else if (rule["func"]) {
998                fn = rule["func"];
999
1000                if (typeof (fn) !== "function") {
1001                    alert("jqv:custom parameter 'function' is no function - " + customRule);
1002                    return;
1003                }
1004
1005                if (!fn(field, rules, i, options))
1006                    return options.allrules[customRule].alertText;
1007            } else {
1008                alert("jqv:custom type not allowed " + customRule);
1009                return;
1010            }
1011        },
1012        /**
1013        * Validate custom function outside of the engine scope
1014        *
1015        * @param {jqObject} field
1016        * @param {Array[String]} rules
1017        * @param {int} i rules index
1018        * @param {Map}
1019        *            user options
1020        * @return an error string if validation failed
1021        */
1022        _funcCall: function (field, rules, i, options) {
1023            var functionName = rules[i + 1];
1024            var fn;
1025            if (functionName.indexOf('.') > -1) {
1026                var namespaces = functionName.split('.');
1027                var scope = window;
1028                while (namespaces.length) {
1029                    scope = scope[namespaces.shift()];
1030                }
1031                fn = scope;
1032            }
1033            else
1034                fn = window[functionName] || options.customFunctions[functionName];
1035            if (typeof (fn) == 'function')
1036                return fn(field, rules, i, options);
1037
1038        },
1039        /**
1040        * Field match
1041        *
1042        * @param {jqObject} field
1043        * @param {Array[String]} rules
1044        * @param {int} i rules index
1045        * @param {Map}
1046        *            user options
1047        * @return an error string if validation failed
1048        */
1049        _equals: function (field, rules, i, options) {
1050            var equalsField = rules[i + 1];
1051
1052            if (field.val() != $("#" + equalsField).val())
1053                return options.allrules.equals.alertText;
1054        },
1055        /**
1056        * Check the maximum size (in characters)
1057        *
1058        * @param {jqObject} field
1059        * @param {Array[String]} rules
1060        * @param {int} i rules index
1061        * @param {Map}
1062        *            user options
1063        * @return an error string if validation failed
1064        */
1065        _maxSize: function (field, rules, i, options) {
1066            var max = rules[i + 1];
1067            var len = field.val().length;
1068
1069            if (len > max) {
1070                var rule = options.allrules.maxSize;
1071                return rule.alertText + max + rule.alertText2;
1072            }
1073        },
1074        /**
1075        * Check the minimum size (in characters)
1076        *
1077        * @param {jqObject} field
1078        * @param {Array[String]} rules
1079        * @param {int} i rules index
1080        * @param {Map}
1081        *            user options
1082        * @return an error string if validation failed
1083        */
1084        _minSize: function (field, rules, i, options) {
1085            var min = rules[i + 1];
1086            var len = field.val().length;
1087
1088            if (len < min) {
1089                var rule = options.allrules.minSize;
1090                return rule.alertText + min + rule.alertText2;
1091            }
1092        },
1093        /**
1094        * Check number minimum value
1095        *
1096        * @param {jqObject} field
1097        * @param {Array[String]} rules
1098        * @param {int} i rules index
1099        * @param {Map}
1100        *            user options
1101        * @return an error string if validation failed
1102        */
1103        _min: function (field, rules, i, options) {
1104            var min = parseFloat(rules[i + 1]);
1105            var len = parseFloat(field.val());
1106
1107            if (len < min) {
1108                var rule = options.allrules.min;
1109                if (rule.alertText2) return rule.alertText + min + rule.alertText2;
1110                return rule.alertText + min;
1111            }
1112        },
1113        /**
1114        * Check number maximum value
1115        *
1116        * @param {jqObject} field
1117        * @param {Array[String]} rules
1118        * @param {int} i rules index
1119        * @param {Map}
1120        *            user options
1121        * @return an error string if validation failed
1122        */
1123        _max: function (field, rules, i, options) {
1124            var max = parseFloat(rules[i + 1]);
1125            var len = parseFloat(field.val());
1126
1127            if (len > max) {
1128                var rule = options.allrules.max;
1129                if (rule.alertText2) return rule.alertText + max + rule.alertText2;
1130                //orefalo: to review, also do the translations
1131                return rule.alertText + max;
1132            }
1133        },
1134        /**
1135        * Checks date is in the past
1136        *
1137        * @param {jqObject} field
1138        * @param {Array[String]} rules
1139        * @param {int} i rules index
1140        * @param {Map}
1141        *            user options
1142        * @return an error string if validation failed
1143        */
1144        _past: function (form, field, rules, i, options) {
1145
1146            var p = rules[i + 1];
1147            var fieldAlt = $(form.find("input[name='" + p.replace(/^#+/, '') + "']"));
1148            var pdate;
1149
1150            if (p.toLowerCase() == "now") {
1151                pdate = new Date();
1152            } else if (undefined != fieldAlt.val()) {
1153                if (fieldAlt.is(":disabled"))
1154                    return;
1155                pdate = methods._parseDate(fieldAlt.val());
1156            } else {
1157                pdate = methods._parseDate(p);
1158            }
1159            var vdate = methods._parseDate(field.val());
1160
1161            if (vdate > pdate) {
1162                var rule = options.allrules.past;
1163                if (rule.alertText2) return rule.alertText + methods._dateToString(pdate) + rule.alertText2;
1164                return rule.alertText + methods._dateToString(pdate);
1165            }
1166        },
1167        /**
1168        * Checks date is in the future
1169        *
1170        * @param {jqObject} field
1171        * @param {Array[String]} rules
1172        * @param {int} i rules index
1173        * @param {Map}
1174        *            user options
1175        * @return an error string if validation failed
1176        */
1177        _future: function (form, field, rules, i, options) {
1178
1179            var p = rules[i + 1];
1180            var fieldAlt = $(form.find("input[name='" + p.replace(/^#+/, '') + "']"));
1181            var pdate;
1182
1183            if (p.toLowerCase() == "now") {
1184                pdate = new Date();
1185            } else if (undefined != fieldAlt.val()) {
1186                if (fieldAlt.is(":disabled"))
1187                    return;
1188                pdate = methods._parseDate(fieldAlt.val());
1189            } else {
1190                pdate = methods._parseDate(p);
1191            }
1192            var vdate = methods._parseDate(field.val());
1193
1194            if (vdate < pdate) {
1195                var rule = options.allrules.future;
1196                if (rule.alertText2)
1197                    return rule.alertText + methods._dateToString(pdate) + rule.alertText2;
1198                return rule.alertText + methods._dateToString(pdate);
1199            }
1200        },
1201        /**
1202        * Checks if valid date
1203        *
1204        * @param {string} date string
1205        * @return a bool based on determination of valid date
1206        */
1207        _isDate: function (value) {
1208            var dateRegEx = new RegExp(/^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$|^(?:(?:(?
1208:0?[13578]|1[02])(\/|-)31)|(?:(?:0?[1,3-9]|1[0-2])(\/|-)(?:29|30)))(\/|-)(?:[1-9]\d\d\d|\d[1-9]\d\d|\d\d[1-9]\d|\d\d\d[1-9])$|^(?:(?:0?[1-9]|1[0-2])(\/|-)(?:0?[1-9]|1\d|2[0-8]))(\/|-)(?:[1-9]\d\d\d|\d[1-9]\d\d|\d\d[1-9]\d|\d\d\d[1-9])$|^(0?2(\/|-)29)(\/|-)(?:(?:0[48]00|[13579][26]00|[2468][048]00)|(?:\d\d)?(?:0[48]|[2468][048]|[13579][26]))$/);
1209            return dateRegEx.test(value);
1210        },
1211        /**
1212        * Checks if valid date time
1213        *
1214        * @param {string} date string
1215        * @return a bool based on determination of valid date time
1216        */
1217        _isDateTime: function (value) {
1218            var dateTimeRegEx = new RegExp(/^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])\s+(1[012]|0?[1-9]){1}:(0?[1-5]|[0-6][0-9]){1}:(0?[0-6]|[0-6][0-9]){1}\s+(am|pm|AM|PM){1}$|^(?:(?:(?:0?[13578]|1[02])(\/|-)31)|(?:(?:0?[1,3-9]|1[0-2])(\/|-)(?:29|30)))(\/|-)(?:[1-9]\d\d\d|\d[1-9]\d\d|\d\d[1-9]\d|\d\d\d[1-9])$|^((1[012]|0?[1-9]){1}\/(0?[1-9]|[12][0-9]|3[01]){1}\/\d{2,4}\s+(1[012]|0?[1-9]){1}:(0?[1-5]|[0-6][0-9]){1}:(0?[0-6]|[0-6][0-9]){1}\s+(am|pm|AM|PM){1})$/);
1219            return dateTimeRegEx.test(value);
1220        },
1221        //Checks if the start date is before the end date
1222        //returns true if end is later than start
1223        _dateCompare: function (start, end) {
1224            return (new Date(start.toString()) < new Date(end.toString()));
1225        },
1226        /**
1227        * Checks date range
1228        *
1229        * @param {jqObject} first field name
1230        * @param {jqObject} second field name
1231        * @return an error string if validation failed
1232        */
1233        _dateRange: function (field, rules, i, options) {
1234            //are not both populated
1235            if ((!options.firstOfGroup[0].value && options.secondOfGroup[0].value) || (options.firstOfGroup[0].value && !options.secondOfGroup[0].value)) {
1236                return options.allrules[rules[i]].alertText + options.allrules[rules[i]].alertText2;
1237            }
1238
1239            //are not both dates
1240            if (!methods._isDate(options.firstOfGroup[0].value) || !methods._isDate(options.secondOfGroup[0].value)) {
1241                return options.allrules[rules[i]].alertText + options.allrules[rules[i]].alertText2;
1242            }
1243
1244            //are both dates but range is off
1245            if (!methods._dateCompare(options.firstOfGroup[0].value, options.secondOfGroup[0].value)) {
1246                return options.allrules[rules[i]].alertText + options.allrules[rules[i]].alertText2;
1247            }
1248        },
1249        /**
1250        * Checks date time range
1251        *
1252        * @param {jqObject} first field name
1253        * @param {jqObject} second field name
1254        * @return an error string if validation failed
1255        */
1256        _dateTimeRange: function (field, rules, i, options) {
1257            //are not both populated
1258            if ((!options.firstOfGroup[0].value && options.secondOfGroup[0].value) || (options.firstOfGroup[0].value && !options.secondOfGroup[0].value)) {
1259                return options.allrules[rules[i]].alertText + options.allrules[rules[i]].alertText2;
1260            }
1261            //are not both dates
1262            if (!methods._isDateTime(options.firstOfGroup[0].value) || !methods._isDateTime(options.secondOfGroup[0].value)) {
1263                return options.allrules[rules[i]].alertText + options.allrules[rules[i]].alertText2;
1264            }
1265            //are both dates but range is off
1266            if (!methods._dateCompare(options.firstOfGroup[0].value, options.secondOfGroup[0].value)) {
1267                return options.allrules[rules[i]].alertText + options.allrules[rules[i]].alertText2;
1268            }
1269        },
1270        /**
1271        * Max number of checkbox selected
1272        *
1273        * @param {jqObject} field
1274        * @param {Array[String]} rules
1275        * @param {int} i rules index
1276        * @param {Map}
1277        *            user options
1278        * @return an error string if validation failed
1279        */
1280        _maxCheckbox: function (form, field, rules, i, options) {
1281
1282            var nbCheck = rules[i + 1];
1283            var groupname = field.attr("name");
1284            var groupSize = form.find("input[name='" + groupname + "']:checked").size();
1285            if (groupSize > nbCheck) {
1286                options.showArrow = false;
1287                if (options.allrules.maxCheckbox.alertText2)
1288                    return options.allrules.maxCheckbox.alertText + " " + nbCheck + " " + options.allrules.maxCheckbox.alertText2;
1289                return options.allrules.maxCheckbox.alertText;
1290            }
1291        },
1292        /**
1293        * Min number of checkbox selected
1294        *
1295        * @param {jqObject} field
1296        * @param {Array[String]} rules
1297        * @param {int} i rules index
1298        * @param {Map}
1299        *            user options
1300        * @return an error string if validation failed
1301        */
1302        _minCheckbox: function (form, field, rules, i, options) {
1303
1304            var nbCheck = rules[i + 1];
1305            var groupname = field.attr("name");
1306            var groupSize = form.find("input[name='" + groupname + "']:checked").size();
1307            if (groupSize < nbCheck) {
1308                options.showArrow = false;
1309                return options.allrules.minCheckbox.alertText + " " + nbCheck + " " + options.allrules.minCheckbox.alertText2;
1310            }
1311        },
1312        /**
1313        * Checks that it is a valid credit card number according to the
1314        * Luhn checksum algorithm.
1315        *
1316        * @param {jqObject} field
1317        * @param {Array[String]} rules
1318        * @param {int} i rules index
1319        * @param {Map}
1320        *            user options
1321        * @return an error string if validation failed
1322        */
1323        _creditCard: function (field, rules, i, options) {
1324            //spaces and dashes may be valid characters, but must be stripped to calculate the checksum.
1325            var valid = false, cardNumber = field.val().replace(/ +/g, '').replace(/-+/g, '');
1326
1327            var numDigits = cardNumber.length;
1328            if (numDigits >= 14 && numDigits <= 16 && parseInt(cardNumber) > 0) {
1329
1330                var sum = 0, i = numDigits - 1, pos = 1, digit, luhn = new String();
1331                do {
1332                    digit = parseInt(cardNumber.charAt(i));
1333                    luhn += (pos++ % 2 == 0) ? digit * 2 : digit;
1334                } while (--i >= 0)
1335
1336                for (i = 0; i < luhn.length; i++) {
1337                    sum += parseInt(luhn.charAt(i));
1338                }
1339                valid = sum % 10 == 0;
1340            }
1341            if (!valid) return options.allrules.creditCard.alertText;
1342        },
1343        /**
1344        * Ajax field validation
1345        *
1346        * @param {jqObject} field
1347        * @param {Array[String]} rules
1348        * @param {int} i rules index
1349        * @param {Map}
1350        *            user options
1351        * @return nothing! the ajax validator handles the prompts itself
1352        */
1353        _ajax: function (field, rules, i, options) {
1354
1355            var errorSelector = rules[i + 1];
1356            var rule = options.allrules[errorSelector];
1357            var extraData = rule.extraData;
1358            var extraDataDynamic = rule.extraDataDynamic;
1359            var data = {
1360                "fieldId": field.attr("id"),
1361                "fieldValue": field.val()
1362            };
1363
1364            if (typeof extraData === "object") {
1365                $.extend(data, extraData);
1366            } else if (typeof extraData === "string") {
1367                var tempData = extraData.split("&");
1368                for (var i = 0; i < tempData.length; i++) {
1369                    var values = tempData[i].split("=");
1370                    if (values[0] && values[0]) {
1371                        data[values[0]] = values[1];
1372                    }
1373                }
1374            }
1375
1376            if (extraDataDynamic) {
1377                var tmpData = [];
1378                var domIds = String(extraDataDynamic).split(",");
1379                for (var i = 0; i < domIds.length; i++) {
1380                    var id = domIds[i];
1381                    if ($(id).length) {
1382                        var inputValue = field.closest("form, .validationEngineContainer").find(id).val();
1383                        var keyValue = id.replace('#', '') + '=' + escape(inputValue);
1384                        data[id.replace('#', '')] = inputValue;
1385                    }
1386                }
1387            }
1388
1389            // If a field change event triggered this we want to clear the cache for this ID
1390            if (options.eventTrigger == "field") {
1391                delete (options.ajaxValidCache[field.attr("id")]);
1392            }
1393
1394            // If there is an error or if the the field is already validated, do not re-execute AJAX
1395            if (!options.isError && !methods._checkAjaxFieldStatus(field.attr("id"), options)) {
1396                $.ajax({
1397                    type: options.ajaxFormValidationMethod,
1398                    url: rule.url,
1399                    cache: false,
1400                    dataType: "json",
1401                    data: data,
1402                    field: field,
1403                    rule: rule,
1404                    methods: methods,
1405                    options: options,
1406                    beforeSend: function () { },
1407                    error: function (data, transport) {
1408                        methods._ajaxError(data, transport);
1409                    },
1410                    success: function (json) {
1411
1412                        // asynchronously called on success, data is the json answer from the server
1413                        var errorFieldId = json[0];
1414                        //var errorField = $($("#" + errorFieldId)[0]);
1415                        var errorField = $("#" + errorFieldId).eq(0);
1416
1417                        // make sure we found the element
1418                        if (errorField.length == 1) {
1419                            var status = json[1];
1420                            // read the optional msg from the server
1421                            var msg = json[2];
1422                            if (!status) {
1423                                // Houston we got a problem - display an red prompt
1424                                options.ajaxValidCache[errorFieldId] = false;
1425                                options.isError = true;
1426
1427                                // resolve the msg prompt
1428                                if (msg) {
1429                                    if (options.allrules[msg]) {
1430                                        var txt = options.allrules[msg].alertText;
1431                                        if (txt) {
1432                                            msg = txt;
1433                                        }
1434                                    }
1435                                }
1436                                else
1437                                    msg = rule.alertText;
1438
1439                                if (options.showPrompts) methods._showPrompt(errorField, msg, "", true, options);
1440                            } else {
1441                                options.ajaxValidCache[errorFieldId] = true;
1442
1443                                // resolves the msg prompt
1444                                if (msg) {
1445                                    if (options.allrules[msg]) {
1446                                        var txt = options.allrules[msg].alertTextOk;
1447                                        if (txt) {
1448                                            msg = txt;
1449                                        }
1450                                    }
1451                                }
1452                                else
1453                                    msg = rule.alertTextOk;
1454
1455                                if (options.showPrompts) {
1456                                    // see if we should display a green prompt
1457                                    if (msg)
1458                                        methods._showPrompt(errorField, msg, "pass", true, options);
1459                                    else
1460                                        methods._closePrompt(errorField);
1461                                }
1462
1463                                // If a submit form triggered this, we want to re-submit the form
1464                                if (options.eventTrigger == "submit")
1465                                    field.closest("form").submit();
1466                            }
1467                        }
1468                        errorField.trigger("jqv.field.result", [errorField, options.isError, msg]);
1469                    }
1470                });
1471
1472                return rule.alertTextLoad;
1473            }
1474        },
1475        /**
1476        * Common method to handle ajax errors
1477        *
1478        * @param {Object} data
1479        * @param {Object} transport
1480        */
1481        _ajaxError: function (data, transport) {
1482            if (data.status == 0 && transport == null)
1483                alert("The page is not served from a server! ajax call failed");
1484            else if (typeof console != "undefined")
1485                console.log("Ajax error: " + data.status + " " + transport);
1486        },
1487        /**
1488        * date -> string
1489        *
1490        * @param {Object} date
1491        */
1492        _dateToString: function (date) {
1493            return date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate();
1494        },
1495        /**
1496        * Parses an ISO date
1497        * @param {String} d
1498        */
1499        _parseDate: function (d) {
1500
1501            var dateParts = d.split("-");
1502            if (dateParts == d)
1503                dateParts = d.split("/");
1504            if (dateParts == d) {
1505                dateParts = d.split(".");
1506                return new Date(dateParts[2], (dateParts[1] - 1), dateParts[0]);
1507            }
1508            return new Date(dateParts[0], (dateParts[1] - 1), dateParts[2]);
1509        },
1510        /**
1511        * Builds or updates a prompt with the given information
1512        *
1513        * @param {jqObject} field
1514        * @param {String} promptText html text to display type
1515        * @param {String} type the type of bubble: 'pass' (green), 'load' (black) anything else (red)
1516        * @param {boolean} ajaxed - use to mark fields than being validated with ajax
1517        * @param {Map} options user options
1518        */
1519        _showPrompt: function (field, promptText, type, ajaxed, options, ajaxform) {
1520            //Check if we need to adjust what element to show the prompt on
1521            if (field.data('jqv-prompt-at') instanceof jQuery) {
1522                field = field.data('jqv-prompt-at');
1523            } else if (field.data('jqv-prompt-at')) {
1524                field = $(field.data('jqv-prompt-at'));
1525            }
1526
1527            var prompt = methods._getPrompt(field);
1528            // The ajax submit errors are not see has an error in the form,
1529            // When the form errors are returned, the engine see 2 bubbles, but those are ebing closed by the engine at the same time
1530            // Because no error was found befor submitting
1531            if (ajaxform) prompt = false;
1532            // Check that there is indded text
1533            if ($.trim(promptText)) {
1534                if (prompt)
1535                    methods._updatePrompt(field, prompt, promptText, type, ajaxed, options);
1536                else
1537                    methods._buildPrompt(field, promptText, type, ajaxed, options);
1538            }
1539        },
1540        /**
1541        * Builds and shades a prompt for the given field.
1542        *
1543        * @param {jqObject} field
1544        * @param {String} promptText html text to display type
1545        * @param {String} type the type of bubble: 'pass' (green), 'load' (black) anything else (red)
1546        * @param {boolean} ajaxed - use to mark fields than being validated with ajax
1547        * @param {Map} options user options
1548        */
1549        _buildPrompt: function (field, promptText, type, ajaxed, options) {
1550
1551            // create the prompt
1552            var prompt = $('<div>');
1553            prompt.addClass(methods._getClassName(field.attr("id")) + "formError");
1554            // add a class name to identify the parent form of the prompt
1555            prompt.addClass("parentForm" + methods._getClassName(field.closest('form, .validationEngineContainer').attr("id")));
1556            prompt.addClass("formError");
1557
1558            switch (type) {
1559                case "pass":
1560                    prompt.addClass("greenPopup");
1561                    break;
1562                case "load":
1563                    prompt.addClass("blackPopup");
1564                    break;
1565                default:
1566                    /* it has error  */
1567                    //alert("unknown popup type:"+type);
1568            }
1569            if (ajaxed)
1570                prompt.addClass("ajaxed");
1571
1572            // create the prompt content
1573            var promptContent = $('<div>').addClass("formErrorContent").html(promptText).appendTo(prompt);
1574
1575            // determine position type
1576            var positionType = field.data("promptPosition") || options.promptPosition;
1577
1578            // create the css arrow pointing at the field
1579            // note that there is no triangle on max-checkbox and radio
1580            if (options.showArrow) {
1581                var arrow = $('<div>').addClass("formErrorArrow");
1582
1583                //prompt positioning adjustment support. Usage: positionType:Xshift,Yshift (for ex.: bottomLeft:+20 or bottomLeft:-20,+10)
1584                if (typeof (positionType) == 'string') {
1585                    var pos = positionType.indexOf(":");
1586                    if (pos != -1)
1587                        positionType = positionType.substring(0, pos);
1588                }
1589
1590                switch (positionType) {
1591                    case "bottomLeft":
1592                    case "bottomRight":
1593                        prompt.find(".formErrorContent").before(arrow);
1594                        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>');
1595                        break;
1596                    case "topLeft":
1597                    case "topRight":
1598                        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>');
1599                        prompt.append(arrow);
1600                        break;
1601                }
1602            }
1603            // Add custom prompt class
1604            if (options.addPromptClass)
1605                prompt.addClass(options.addPromptClass);
1606
1607            // Add custom prompt class defined in element
1608            var requiredOverride = field.attr('data-required-class');
1609            if (requiredOverride !== undefined) {
1610                prompt.addClass(requiredOverride);
1611            } else {
1612                if (options.prettySelect) {
1613                    if ($('#' + field.attr('id')).next().is('select')) {
1614                        var prettyOverrideClass = $('#' + field.attr('id').substr(options.usePrefix.length).substring(options.useSuffix.length)).attr('data-required-class');
1615                        if (prettyOverrideClass !== undefined) {
1616                            prompt.addClass(prettyOverrideClass);
1617                        }
1618                    }
1619                }
1620            }
1621
1622            prompt.css({
1623                "opacity": 0
1624            });
1625            if (positionType === 'inline') {
1626                prompt.addClass("inline");
1627                if (typeof field.attr('data-prompt-target') !== 'undefined' && $('#' + field.attr('data-prompt-target')).length > 0) {
1628                    prompt.appendTo($('#' + field.attr('data-prompt-target')));
1629                } else {
1630                    field.after(prompt);
1631                }
1632            } else {
1633                field.before(prompt);
1634            }
1635
1636            var pos = methods._calculatePosition(field, prompt, options);
1637            prompt.css({
1638                'position': positionType === 'inline' ? 'relative' : 'absolute',
1639                "top": pos.callerTopPosition,
1640                "left": pos.callerleftPosition,
1641                "marginTop": pos.marginTopSize,
1642                "opacity": 0,
1643            }).data("callerField", field);
1644            
1645            var leftoffset = prompt.width() + parseInt(pos.callerleftPosition) + prompt.parent().offset().left;
1646
1647            if( leftoffset > $(window).width()){
1648                prompt.css({
1649                "left":parseInt(pos.callerleftPosition) - (leftoffset - $(window).width())
1650                })
1651            }
1652
1653
1654            if (options.autoHidePrompt) {
1655                setTimeout(function () {
1656                    prompt.animate({
1657                        "opacity": 0
1658                    }, function () {
1659                        prompt.closest('.formErrorOuter').remove();
1660                        prompt.remove();
1661                    });
1662                }, options.autoHideDelay);
1663            }
1664            return prompt.animate({
1665                "opacity": 0.87
1666            });
1667        },
1668        /**
1669        * Updates the prompt text field - the field for which the prompt
1670        * @param {jqObject} field
1671        * @param {String} promptText html text to display type
1672        * @param {String} type the type of bubble: 'pass' (green), 'load' (black) anything else (red)
1673        * @param {boolean} ajaxed - use to mark fields than being validated with ajax
1674        * @param {Map} options user options
1675        */
1676        _updatePrompt: function (field, prompt, promptText, type, ajaxed, options, noAnimation) {
1677
1678            if (prompt) {
1679                if (typeof type !== "undefined") {
1680                    if (type == "pass")
1681                        prompt.addClass("greenPopup");
1682                    else
1683                        prompt.removeClass("greenPopup");
1684
1685                    if (type == "load")
1686                        prompt.addClass("blackPopup");
1687                    else
1688                        prompt.removeClass("blackPopup");
1689                }
1690                if (ajaxed)
1691                    prompt.addClass("ajaxed");
1692                else
1693                    prompt.removeClass("ajaxed");
1694
1695                prompt.find(".formErrorContent").html(promptText);
1696
1697                var pos = methods._calculatePosition(field, prompt, options);
1698                var css = { "top": pos.callerTopPosition,
1699                    "left": pos.callerleftPosition,
1700                    "marginTop": pos.marginTopSize
1701                };
1702
1703
1704                var leftoffset = prompt.width() + parseInt(pos.callerleftPosition) + prompt.parent().offset().left;
1705
1706                if( leftoffset > $(window).width()){
1707                    css.left = parseInt(pos.callerleftPosition) - (leftoffset - $(window).width());
1708                }
1709
1710                if (noAnimation){
1711                    prompt.css(css);
1712                }else{
1713                    prompt.animate(css);
1714                }
1715
1716
1717
1718            }
1719        },
1720        /**
1721        * Closes the prompt associated with the given field
1722        *
1723        * @param {jqObject}
1724        *            field
1725        */
1726        _closePrompt: function (field) {
1727            var prompt = methods._getPrompt(field);
1728            if (prompt)
1729                prompt.fadeTo("fast", 0, function () {
1730                    prompt.parent('.formErrorOuter').remove();
1731                    prompt.remove();
1732                });
1733        },
1734        closePrompt: function (field) {
1735            return methods._closePrompt(field);
1736        },
1737        /**
1738        * Returns the error prompt matching the field if any
1739        *
1740        * @param {jqObject}
1741        *            field
1742        * @return undefined or the error prompt (jqObject)
1743        */
1744        _getPrompt: function (field) {
1745            var formId = $(field).closest('form, .validationEngineContainer').attr('id');
1746            var className = methods._getClassName(field.attr("id")) + "formError";
1747            var match = $("." + methods._escapeExpression(className) + '.parentForm' + methods._getClassName(formId))[0];
1748            if (match)
1749                return $(match);
1750        },
1751        /**
1752        * Returns the escapade classname
1753        *
1754        * @param {selector}
1755        *            className
1756        */
1757        _escapeExpression: function (selector) {
1758            return selector.replace(/([#;&,\.\+\*\~':"\!\^$\[\]\(\)=>\|])/g, "\\$1");
1759        },
1760        /**
1761        * returns true if we are in a RTLed document
1762        *
1763        * @param {jqObject} field
1764        */
1765        isRTL: function (field) {
1766            var $document =
1766 $(document);
1767            var $body = $('body');
1768            var rtl =
1769				(field && field.hasClass('rtl')) ||
1770				(field && (field.attr('dir') || '').toLowerCase() === 'rtl') ||
1771				$document.hasClass('rtl') ||
1772				($document.attr('dir') || '').toLowerCase() === 'rtl' ||
1773				$body.hasClass('rtl') ||
1774				($body.attr('dir') || '').toLowerCase() === 'rtl';
1775            return Boolean(rtl);
1776        },
1777        /**
1778        * Calculates prompt position
1779        *
1780        * @param {jqObject}
1781        *            field
1782        * @param {jqObject}
1783        *            the prompt
1784        * @param {Map}
1785        *            options
1786        * @return positions
1787        */
1788        _calculatePosition: function (field, promptElmt, options) {
1789
1790            var promptTopPosition, promptleftPosition, marginTopSize;
1791            var fieldWidth = field.width();
1792            var fieldLeft = field.position().left;
1793            var fieldTop = field.position().top;
1794            var fieldHeight = field.height();
1795            var promptHeight = promptElmt.height();
1796
1797
1798            // is the form contained in an overflown container?
1799            promptTopPosition = promptleftPosition = 0;
1800            // compensation for the arrow
1801            marginTopSize = -promptHeight;
1802
1803
1804            //prompt positioning adjustment support
1805            //now you can adjust prompt position
1806            //usage: positionType:Xshift,Yshift
1807            //for example:
1808            //   bottomLeft:+20 means bottomLeft position shifted by 20 pixels right horizontally
1809            //   topRight:20, -15 means topRight position shifted by 20 pixels to right and 15 pixels to top
1810            //You can use +pixels, - pixels. If no sign is provided than + is default.
1811            var positionType = field.data("promptPosition") || options.promptPosition;
1812            var shift1 = "";
1813            var shift2 = "";
1814            var shiftX = 0;
1815            var shiftY = 0;
1816            if (typeof (positionType) == 'string') {
1817                //do we have any position adjustments ?
1818                if (positionType.indexOf(":") != -1) {
1819                    shift1 = positionType.substring(positionType.indexOf(":") + 1);
1820                    positionType = positionType.substring(0, positionType.indexOf(":"));
1821
1822                    //if any advanced positioning will be needed (percents or something else) - parser should be added here
1823                    //for now we use simple parseInt()
1824
1825                    //do we have second parameter?
1826                    if (shift1.indexOf(",") != -1) {
1827                        shift2 = shift1.substring(shift1.indexOf(",") + 1);
1828                        shift1 = shift1.substring(0, shift1.indexOf(","));
1829                        shiftY = parseInt(shift2);
1830                        if (isNaN(shiftY)) shiftY = 0;
1831                    };
1832
1833                    shiftX = parseInt(shift1);
1834                    if (isNaN(shift1)) shift1 = 0;
1835
1836                };
1837            };
1838
1839
1840            switch (positionType) {
1841                default:
1842                case "topRight":
1843                  
1844                    promptleftPosition += fieldLeft + fieldWidth - 30;
1845                    promptTopPosition += fieldTop;
1846                    break;
1847
1848                case "topLeft":
1849                    promptTopPosition += fieldTop;
1850                    promptleftPosition += fieldLeft;
1851                    break;
1852
1853                case "centerRight":
1854                    promptTopPosition = fieldTop + 4;
1855                    marginTopSize = 0;
1856                    promptleftPosition = fieldLeft + field.outerWidth(true) + 5;
1857                    break;
1858                case "centerLeft":
1859                    promptleftPosition = fieldLeft - (promptElmt.width() + 2);
1860                    promptTopPosition = fieldTop + 4;
1861                    marginTopSize = 0;
1862
1863                    break;
1864
1865                case "bottomLeft":
1866                    promptTopPosition = fieldTop + field.height() + 5;
1867                    marginTopSize = 0;
1868                    promptleftPosition = fieldLeft;
1869                    break;
1870                case "bottomRight":
1871                    promptleftPosition = fieldLeft + fieldWidth - 30;
1872                    promptTopPosition = fieldTop + field.height() + 5;
1873                    marginTopSize = 0;
1874                    break;
1875                case "inline":
1876                    promptleftPosition = 0;
1877                    promptTopPosition = 0;
1878                    marginTopSize = 0;
1879            };
1880
1881
1882
1883            //apply adjusments if any
1884            promptleftPosition += shiftX;
1885            promptTopPosition += shiftY;
1886
1887            return {
1888                "callerTopPosition": promptTopPosition + "px",
1889                "callerleftPosition": promptleftPosition + "px",
1890                "marginTopSize": marginTopSize + "px"
1891            };
1892        },
1893        /**
1894        * Saves the user options and variables in the form.data
1895        *
1896        * @param {jqObject}
1897        *            form - the form where the user option should be saved
1898        * @param {Map}
1899        *            options - the user options
1900        * @return the user options (extended from the defaults)
1901        */
1902        _saveOptions: function (form, options) {
1903
1904            // is there a language localisation ?
1905            if ($.validationEngineLanguage)
1906                var allRules = $.validationEngineLanguage.allRules;
1907            else
1908                $.error("jQuery.validationEngine rules are not loaded, plz add localization files to the page");
1909            // --- Internals DO NOT TOUCH or OVERLOAD ---
1910            // validation rules and i18
1911            $.validationEngine.defaults.allrules = allRules;
1912
1913            var userOptions = $.extend(true, {}, $.validationEngine.defaults, options);
1914
1915            form.data('jqv', userOptions);
1916            return userOptions;
1917        },
1918
1919        /**
1920        * Removes forbidden characters from class name
1921        * @param {String} className
1922        */
1923        _getClassName: function (className) {
1924            if (className)
1925                return className.replace(/:/g, "_").replace(/\./g, "_");
1926        },
1927        /**
1928        * Escape special character for jQuery selector
1929        * http://totaldev.com/content/escaping-characters-get-valid-jquery-id
1930        * @param {String} selector
1931        */
1932        _jqSelector: function (str) {
1933            return str.replace(/([;&,\.\+\*\~':"\!\^#$%@\[\]\(\)=>\|])/g, '\\$1');
1934        },
1935        /**
1936        * Conditionally required field
1937        *
1938        * @param {jqObject} field
1939        * @param {Array[String]} rules
1940        * @param {int} i rules index
1941        * @param {Map}
1942        * user options
1943        * @return an error string if validation failed
1944        */
1945        _condRequired: function (field, rules, i, options) {
1946            var idx, dependingField;
1947
1948            for (idx = (i + 1); idx < rules.length; idx++) {
1949                dependingField = jQuery("#" + rules[idx]).first();
1950
1951                /* Use _required for determining wether dependingField has a value.
1952                * There is logic there for handling all field types, and default value; so we won't replicate that here
1953                * Indicate this special use by setting the last parameter to true so we only validate the dependingField on chackboxes and radio buttons (#462)
1954                */
1955                if (dependingField.length && methods._required(dependingField, ["required"], 0, options, true) == undefined) {
1956                    /* We now know any of the depending fields has a value,
1957                    * so we can validate this field as per normal required code
1958                    */
1959                    return methods._required(field, ["required"], 0, options);
1960                }
1961            }
1962        },
1963
1964        _submitButtonClick: function (event) {
1965            var button = $(this);
1966            var form = button.closest('form, .validationEngineContainer');
1967            form.data("jqv_submitButton", button.attr("id"));
1968        }
1969    };
1970
1971    /**
1972    * Plugin entry point.
1973    * You may pass an action as a parameter or a list of options.
1974    * if none, the init and attach methods are being called.
1975    * Remember: if you pass options, the attached method is NOT called automatically
1976    *
1977    * @param {String}
1978    *            method (optional) action
1979    */
1980    $.fn.validationEngine = function (method) {
1981
1982        var form = $(this);
1983        if (!form[0]) return form;  // stop here if the form does not exist
1984
1985        if (typeof (method) == 'string' && method.charAt(0) != '_' && methods[method]) {
1986
1987            // make sure init is called once
1988            if (method != "showPrompt" && method != "hide" && method != "hideAll")
1989                methods.init.apply(form);
1990
1991            return methods[method].apply(form, Array.prototype.slice.call(arguments, 1));
1992        } else if (typeof method == 'object' || !method) {
1993
1994            // default constructor with or without arguments
1995            methods.init.apply(form, arguments);
1996            return methods.attach.apply(form);
1997        } else {
1998            $.error('Method ' + method + ' does not exist in jQuery.validationEngine');
1999        }
2000    };
2001
2002
2003
2004    // LEAK GLOBAL OPTIONS
2005    $.validationEngine = { fieldIdCounter: 0, defaults: {
2006
2007        // Name of the event triggering field validation
2008        validationEventTrigger: "blur",
2009        // Automatically scroll viewport to the first error
2010        scroll: true,
2011        // Focus on the first input
2012        focusFirstField: true,
2013        // Show prompts, set to false to disable prompts
2014        showPrompts: true,
2015        // Should we attempt to validate non-visible input fields contained in the form? (Useful in cases of tabbed containers, e.g. jQuery-UI tabs)
2016        validateNonVisibleFields: false,
2017        // Opening box position, possible locations are: topLeft,
2018        // topRight, bottomLeft, centerRight, bottomRight, inline
2019        // inline gets inserted after the validated field or into an element specified in data-prompt-target
2020        promptPosition: "topRight",
2021        bindMethod: "bind",
2022        // internal, automatically set to true when it parse a _ajax rule
2023        inlineAjax: false,
2024        // if set to true, the form data is sent asynchronously via ajax to the form.action url (get)
2025        ajaxFormValidation: false,
2026        // The url to send the submit ajax validation (default to action)
2027        ajaxFormValidationURL: false,
2028        // HTTP method used for ajax validation
2029        ajaxFormValidationMethod: 'get',
2030        // Ajax form validation callback method: boolean onComplete(form, status, errors, options)
2031        // retuns false if the form.submit event needs to be canceled.
2032        onAjaxFormComplete: $.noop,
2033        // called right before the ajax call, may return false to cancel
2034        onBeforeAjaxFormValidation: $.noop,
2035        // Stops form from submitting and execute function assiciated with it
2036        onValidationComplete: false,
2037
2038        // Used when you have a form fields too close and the errors messages are on top of other disturbing viewing messages
2039        doNotShowAllErrosOnSubmit: false,
2040        // Object where you store custom messages to override the default error messages
2041        custom_error_messages: {},
2042        // true if you want to vind the input fields
2043        binded: true,
2044        // set to true, when the prompt arrow needs to be displayed
2045        showArrow: true,
2046        // did one of the validation fail ? kept global to stop further ajax validations
2047        isError: false,
2048        // Limit how many displayed errors a field can have
2049        maxErrorsPerField: false,
2050
2051        // Caches field validation status, typically only bad status are created.
2052        // the array is used during ajax form validation to detect issues early and prevent an expensive submit
2053        ajaxValidCache: {},
2054        // Auto update prompt position after window resize
2055        autoPositionUpdate: false,
2056
2057        InvalidFields: [],
2058        onFieldSuccess: false,
2059        onFieldFailure: false,
2060        onSuccess: false,
2061        onFailure: false,
2062        validateAttribute: "class",
2063        addSuccessCssClassToField: "",
2064        addFailureCssClassToField: "",
2065
2066        // Auto-hide prompt
2067        autoHidePrompt: false,
2068        // Delay before auto-hide
2069        autoHideDelay: 10000,
2070        // Fade out duration while hiding the validations
2071        fadeDuration: 0.3,
2072        // Use Prettify select library
2073        prettySelect: false,
2074        // Add css class on prompt
2075        addPromptClass: "",
2076        // Custom ID uses prefix
2077        usePrefix: "",
2078        // Custom ID uses suffix
2079        useSuffix: "",
2080        // Only show one message per error prompt
2081        showOneMessage: false
2082    }
2083    };
2084    $(function () { $.validationEngine.defaults.promptPosition = methods.isRTL() ? 'topLeft' : "topRight" });
2085})(jQuery);
2086

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.