PageSourceSearch

https://beautymylab.com/js/raku2/jquery.validationEngine.js

js beautymylab.com collected 2026-09-30 22:02:11 UTC 69,332 bytes, 2,002 lines download raw bytes

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

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.