PageSourceSearch

https://kyoto-tengudo.jp/wp-content/themes/revonet/js/jquery.validationEngine.js?ver=2.6.2

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

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.