PageSourceSearch

https://viamediapromotions.com/js/jquery.validationEngine.js

js viamediapromotions.com collected 2026-10-10 02:37:07 UTC 49,095 bytes, 1,239 lines download raw bytes

1/*
2 * Inline Form Validation Engine 2.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    var methods = {
16
17        /**
18         * Kind of the constructor, called before any action
19         * @param {Map} user options
20         */
21        init: function(options) {
22            var form = this;
23            if (!form.data('jqv') || form.data('jqv') == null ) {
24                methods._saveOptions(form, options);
25
26                // bind all formError elements to close on click
27                //$(".formError").live("click", function() {
28				$(".formError").on("click", function () {
29                    $(this).fadeOut(150, function() {
30
31                        // remove prompt once invisible
32                        $(this).remove();
33                    });
34                });
35            }
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            var form = this;
44            var options;
45
46            if(userOptions)
47                options = methods._saveOptions(form, userOptions);
48            else
49                options = form.data('jqv');
50			
51			var validateAttribute = (form.find("[data-validation-engine*=validate]")) ? "data-validation-engine" : "class";
52			
53            if (!options.binded) {
54					if (options.bindMethod == "bind"){
55						
56						// bind fields
57                        form.find("[class*=validate]:not([type=checkbox])").bind(options.validationEventTrigger, methods._onFieldEvent);
58                        form.find("[class*=validate][type=checkbox]").bind("click", methods._onFieldEvent);
59
60                        // bind form.submit
61                        form.bind("submit", methods._onSubmitEvent);
62					} else if (options.bindMethod == "live") {
63                        // bind fields with LIVE (for persistant state)
64                        form.find("[class*=validate]:not([type=checkbox])").live(options.validationEventTrigger, methods._onFieldEvent);
65                        form.find("[class*=validate][type=checkbox]").live("click", methods._onFieldEvent);
66
67                        // bind form.submit
68                        form.live("submit", methods._onSubmitEvent);
69					}
70
71                options.binded = true;
72            }
73
74        },
75        /**
76         * Unregisters any bindings that may point to jQuery.validaitonEngine
77         */
78        detach: function() {
79            var form = this;
80            var options = form.data('jqv');
81            if (options.binded) {
82
83                // unbind fields
84                form.find("[class*=validate]").not("[type=checkbox]").unbind(options.validationEventTrigger, methods._onFieldEvent);
85                form.find("[class*=validate][type=checkbox]").unbind("click", methods._onFieldEvent);
86                // unbind form.submit
87                form.unbind("submit", methods.onAjaxFormComplete);
88                
89               
90                // unbind live fields (kill)
91                form.find("[class*=validate]").not("[type=checkbox]").die(options.validationEventTrigger, methods._onFieldEvent);
92                form.find("[class*=validate][type=checkbox]").die("click", methods._onFieldEvent);
93                // unbind form.submit
94                form.die("submit", methods.onAjaxFormComplete);
95                
96                form.removeData('jqv');
97            }
98        },
99        /**
100         * Validates the form fields, shows prompts accordingly.
101         * Note: There is no ajax form validation with this method, only field ajax validation are evaluated
102         *
103         * @return true if the form validates, false if it fails
104         */
105        validate: function() {
106            return methods._validateFields(this);
107        },
108        /**
109         * Validates one field, shows prompt accordingly.
110         * Note: There is no ajax form validation with this method, only field ajax validation are evaluated
111         *
112         * @return true if the form validates, false if it fails
113         */
114        validateField: function(el) {
115            var options = $(this).data('jqv');
116            return methods._validateField($(el), options);
117        },
118        /**
119         * Validates the form fields, shows prompts accordingly.
120         * Note: this methods performs fields and form ajax validations(if setup)
121         *
122         * @return true if the form validates, false if it fails, undefined if ajax is used for form validation
123         */
124        validateform: function() {
125            return methods._onSubmitEvent.call(this);
126        },
127        /**
128         * Displays a prompt on a element.
129         * Note that the element needs an id!
130         *
131         * @param {String} promptText html text to display type
132         * @param {String} type the type of bubble: 'pass' (green), 'load' (black) anything else (red)
133         * @param {String} possible values topLeft, topRight, bottomLeft, centerRight, bottomRight
134         */
135        showPrompt: function(promptText, type, promptPosition, showArrow) {
136
137            var form = this.closest('form');
138            var options = form.data('jqv');
139            // No option, take default one
140			if(!options) options = methods._saveOptions(this, options);
141            if(promptPosition)
142                options.promptPosition=promptPosition;
143            options.showArrow = showArrow==true;
144
145            methods._showPrompt(this, promptText, type, false, options);
146        },
147        /**
148         * Closes all error prompts on the page
149         */
150        hidePrompt: function() {
151        	var promptClass =  "."+ methods._getClassName($(this).attr("id")) + "formError";
152            $(promptClass).fadeTo("fast", 0.3, function() {
153                $(this).remove();
154            });
155        },
156        /**
157         * Closes form error prompts, CAN be invidual
158         */
159        hide: function() {
160			var closingtag;
161        	if($(this).is("form")){
162        		closingtag = "parentForm"+$(this).attr('id');
163        	}else{
164        		closingtag = $(this).attr('id') +"formError";
165        	}
166            $('.'+closingtag).fadeTo("fast", 0.3, function() {
167                $(this).remove();
168            });
169        },
170        /**
171         * Closes all error prompts on the page
172         */
173        hideAll: function() {
174            $('.formError').fadeTo("fast", 0.3, function() {
175                $(this).remove();
176            });
177        },
178        /**
179         * Typically called when user exists a field using tab or a mouse click, triggers a field
180         * validation
181         */
182        _onFieldEvent: function() {
183            var field = $(this);
184            var form = field.closest('form');
185            var options = form.data('jqv');
186            // validate the current field
187            methods._validateField(field, options);
188        },
189        /**
190         * Called when the form is submited, shows prompts accordingly
191         *
192         * @param {jqObject}
193         *            form
194         * @return false if form submission needs to be cancelled
195         */
196        _onSubmitEvent: function() {
197            var form = $(this);
198 			var options = form.data('jqv');
199   
200			// validate each field (- skip field ajax validation, no necessary since we will perform an ajax form validation)
201            var r=methods._validateFields(form, true);
202		
203            if (r && options.ajaxFormValidation) {
204                methods._validateFormWithAjax(form, options);
205                return false;
206            }
207
208            if(options.onValidationComplete) {
209                options.onValidationComplete(form, r);
210                return false;
211            }
212            return r;
213        },
214
215        /**
216         * Return true if the ajax field validations passed so far
217         * @param {Object} options
218         * @return true, is all ajax validation passed so far (remember aja
218x is async)
219         */
220        _checkAjaxStatus: function(options) {
221            var status = true;
222            $.each(options.ajaxValidCache, function(key, value) {
223                if (!value) {
224                    status = false;
225                    // break the each
226                    return false;
227                }
228            });
229            return status;
230        },
231        /**
232         * Validates form fields, shows prompts accordingly
233         *
234         * @param {jqObject}
235         *            form
236         * @param {skipAjaxFieldValidation}
237         *            boolean - when set to true, ajax field validation is skipped, typically used when the submit button is clicked
238         *
239         * @return true if form is valid, false if not, undefined if ajax form validation is done
240         */
241        _validateFields: function(form, skipAjaxValidation) {
242            var options = form.data('jqv');
243
244            // this variable is set to true if an error is found
245            var errorFound = false;
246			
247			// Trigger hook, start validation
248			form.trigger("jqv.form.validating");
249            // first, evaluate status of non ajax fields
250            form.find('[class*=validate]').not(':hidden').each( function() {
251                var field = $(this);
252                errorFound |= methods._validateField(field, options, skipAjaxValidation);
253            });
254            // second, check to see if all ajax calls completed ok
255            // errorFound |= !methods._checkAjaxStatus(options);
256			
257            // thrird, check status and scroll the container accordingly
258			form.trigger("jqv.form.result", [errorFound]);
259			
260            if (errorFound) {
261				
262                if (options.scroll) {
263
264                    // get the position of the first error, there should be at least one, no need to check this
265                    //var destination = form.find(".formError:not('.greenPopup'):first").offset().top;
266
267                    // look for the visually top prompt
268                    var destination = Number.MAX_VALUE;
269                    var fixleft = 0;
270                    var lst = $(".formError:not('.greenPopup')");
271
272                    for (var i = 0; i < lst.length; i++) {
273                        var d = $(lst[i]).offset().top;
274                        if (d < destination){
275                            destination = d;
276                            fixleft = $(lst[i]).offset().left;
277                        }
278                    }
279
280                    if (!options.isOverflown)
281                        $("html:not(:animated),body:not(:animated)").animate({
282                            scrollTop: destination,
283                            scrollLeft: fixleft
284                        }, 1100);
285                    else {
286                        var overflowDIV = $(options.overflownDIV);
287                        var scrollContainerScroll = overflowDIV.scrollTop();
288                        var scrollContainerPos = -parseInt(overflowDIV.offset().top);
289
290                        destination += scrollContainerScroll + scrollContainerPos - 5;
291                        var scrollContainer = $(options.overflownDIV + ":not(:animated)");
292
293                        scrollContainer.animate({
294                            scrollTop: destination
295                        }, 1100);
296
297                        $("html:not(:animated),body:not(:animated)").animate({
298                            scrollTop: overflowDIV.offset().top,
299                            scrollLeft: fixleft
300                        }, 1100);
301                    }
302                }
303                return false;
304            }
305            return true;
306        },
307        /**
308         * This method is called to perform an ajax form validation.
309         * During this process all the (field, value) pairs are sent to the server which returns a list of invalid fields or true
310         *
311         * @param {jqObject} form
312         * @param {Map} options
313         */
314        _validateFormWithAjax: function(form, options) {
315
316            var data = form.serialize();
317			var url = (options.ajaxFormValidationURL) ? options.ajaxFormValidationURL : form.attr("action");
318            $.ajax({
319                type: "GET",
320                url: url,
321                cache: false,
322                dataType: "json",
323                data: data,
324                form: form,
325                methods: methods,
326                options: options,
327                beforeSend: function() {
328                    return options.onBeforeAjaxFormValidation(form, options);
329                },
330                error: function(data, transport) {
331                    methods._ajaxError(data, transport);
332                },
333                success: function(json) {
334
335                    if (json !== true) {
336
337                        // getting to this case doesn't necessary means that the form is invali
337d
338                        // the server may return green or closing prompt actions
339                        // this flag helps figuring it out
340                        var errorInForm=false;
341                        for (var i = 0; i < json.length; i++) {
342                            var value = json[i];
343						
344                            var errorFieldId = value[0];
345                            var errorField = $($("#" + errorFieldId)[0]);
346							
347                            // make sure we found the element
348                            if (errorField.length == 1) {
349								
350                                // promptText or selector
351                                var msg = value[2];
352								// if the field is valid
353                                if (value[1] == true) {
354
355                                    if (msg == ""  || !msg){
356                                        // if for some reason, status==true and error="", just close the prompt
357                                        methods._closePrompt(errorField);
358                                    } else {
359                                        // the field is valid, but we are displaying a green prompt
360                                        if (options.allrules[msg]) {
361                                            var txt = options.allrules[msg].alertTextOk;
362                                            if (txt)
363                                                msg = txt;
364                                        }
365                                        methods._showPrompt(errorField, msg, "pass", false, options, true);
366                                    }
367
368                                } else {
369                                    // the field is invalid, show the red error prompt
370                                    errorInForm|=true;
371                                    if (options.allrules[msg]) {
372                                        var txt = options.allrules[msg].alertText;
373                                        if (txt)
374                                            msg = txt;
375                                    }
376                                    methods._showPrompt(errorField, msg, "", false, options, true);
377                                }
378                            }
379                        }
380                        options.onAjaxFormComplete(!errorInForm, form, json, options);
381                    } else
382                        options.onAjaxFormComplete(true, form, "", options);
383                }
384            });
385
386        },
387        /**
388         * Validates field, shows prompts accordingly
389         *
390         * @param {jqObject}
391         *            field
392         * @param {Array[String]}
393         *            field's validation rules
394         * @param {Map}
395         *            user options
396         * @return true if field is valid
397         */
398        _validateField: function(field, options, skipAjaxValidation) {
399            if (!field.attr("id"))
400                $.error("jQueryValidate: an ID attribute is required for this field: " + field.attr("name") + " class:" +
401                field.attr("class"));
402
403            var rulesParsing = field.attr('class');
404            var getRules = /validate\[(.*)\]/.exec(rulesParsing);
405            if (!getRules)
406                return false;
407            var str = getRules[1];
408            var rules = str.split(/\[|,|\]/);
409
410            // true if we ran the ajax validation, tells the logic to stop messing with prompts
411            var isAjaxValidator = false;
412            var fieldName = field.attr("name");
413            var promptText = "";
414			var required = false;
415            options.isError = false;
416            options.showArrow = true;
417
418            for (var i = 0; i < rules.length; i++) {
419
420                var errorMsg = undefined;
421                switch (rules[i]) {
422
423                    case "required":
424                        required = true;
425                        errorMsg = methods._required(field, rules, i, options);
426                        break;
427                    case "custom":
428                        errorMsg = methods._customRegex(field, rules, i, options);
429                        break;
430                    case "ajax":
431                        // ajax has its own prompts handling technique
432						if(!skipAjaxValidation){
433							errorMsg = methods._ajax(field, rules, i, options);
434	                        isAjaxValidator = true;
435							
436						}
437                        break;
438                    case "minSize":
439                        errorMsg = methods._minSize(field, rules, i, options);
440                        break;
441                    case "maxSize":
442                        errorMsg = methods._maxSize(field, rules, i, options);
443                        break;
444                    case "min":
445                        errorMsg = methods._min(field, rules, i, options);
446                        break;
447                    case "max":
448                        errorMsg = methods._max(field, rules, i, options);
449                        break;
450                    case "past":
451                        errorMsg = methods._past(field, rules, i, options);
452                        break;
453                    case "future":
454                        errorMsg = methods._future(field, rules, i, options);
455                        break;
456                    case "maxCheckbox":
457                        errorMsg = methods._maxCheckbox(field, rules, i, options);
458                        field = $($("input[name='" + fieldName + "']"));
459                        break;
460                    case "minCheckbox":
461                        errorMsg = methods._minCheckbox(field, rules, i, options);
462                        field = $($("input[name='" + fieldName + "']"));
463                        break;
464                    case "equals":
465                        errorMsg = methods._equals(field, rules, i, options);
466                        break;
467                    case "funcCall":
468                        errorMsg = methods._funcCall(field, rules, i, options);
469                        break;
470
471                    default:
472                    //$.error("jQueryValidator rule not found"+rules[i]);
473                }
474                if (errorMsg !== undefined) {
475                    promptText += errorMsg + "<br/>";
476                    options.isError = true;
477					
478                }
479
480            }
481            // If the rules required is not added, an empty field is not validated
482            if(!required){
483            	if(field.val() == "") options.isError = false;
484            }
485            // Hack for radio/checkbox group button, the validation go into the
486            // first radio/checkbox of the group
487            var fieldType = field.attr("type");
488
489            if ((fieldType == "radio" || fieldType == "checkbox") && $("input[name='" + fieldName + "']").size() > 1) {
490                field = $($("input[name='" + fieldName + "'][type!=hidden]:first"));
491                options.showArrow = false;
492            }
493
494            if (options.isError){
495				
496                methods._showPrompt(field, promptText, "", false, options);
497            }else{
498				if (!isAjaxValidator) methods._closePrompt(field);
499			}
500			field.trigger("jqv.field.result", [field, options.isError, promptText]);
501            return options.isError;
502        },
503        /**
504         * Required validation
505         *
506         * @param {jqObject} field
507         * @param {Array[String]} rules
508         * @param {int} i rules index
509         * @param {Map}
510         *            user options
511         * @return an error string if validation failed
512         */
513        _required: function(field, rules, i, options) {
514            switch (field.attr("type")) {
515                case "text":
516                case "password":
517                case "textarea":
518                case "file":
519                default:
520                    if (!field.val())
521                        return options.allrules[rules[i]].alertText;
522                    break;
523                case "radio":
524                case "checkbox":
525                    var name = field.attr("name");
526                    if ($("input[name='" + name + "']:checked").size() == 0) {
527
528                        if ($("input[name='" + name + "']").size() == 1)
529                            return options.allrules[rules[i]].alertTextCheckboxe;
530                        else
531                            return options.allrules[rules[i]].alertTextCheckboxMultiple;
532                    }
533                    break;
534                // required for <select>
535                case "select-one":
536                    // added by [email protected] for select boxes, Thank y
536ou
537                    if (!field.val())
538                        return options.allrules[rules[i]].alertText;
539                    break;
540                case "select-multiple":
541                    // added by [email protected] for select boxes, Thank you
542                    if (!field.find("option:selected").val())
543                        return options.allrules[rules[i]].alertText;
544                    break;
545            }
546        },
547        /**
548         * Validate Regex rules
549         *
550         * @param {jqObject} field
551         * @param {Array[String]} rules
552         * @param {int} i rules index
553         * @param {Map}
554         *            user options
555         * @return an error string if validation failed
556         */
557        _customRegex: function(field, rules, i, options) {
558            var customRule = rules[i + 1];
559			var rule = options.allrules[customRule];
560			if(!rule) {
561				alert("jqv:custom rule not found "+customRule);
562				return;
563			}
564			
565			var ex=rule.regex;
566			if(!ex) {
567				alert("jqv:custom regex not found "+customRule);
568				return;
569			}
570            var pattern = new RegExp(ex);
571
572            if (!pattern.test(field.val()))
573                return options.allrules[customRule].alertText;
574        },
575        /**
576         * Validate custom function outside of the engine scope
577         *
578         * @param {jqObject} field
579         * @param {Array[String]} rules
580         * @param {int} i rules index
581         * @param {Map}
582         *            user options
583         * @return an error string if validation failed
584         */
585        _funcCall: function(field, rules, i, options) {
586            var functionName = rules[i + 1];
587            var fn = window[functionName];
588            if (typeof(fn) == 'function')
589                return fn(field, rules, i, options);
590
591        },
592        /**
593         * Field match
594         *
595         * @param {jqObject} field
596         * @param {Array[String]} rules
597         * @param {int} i rules index
598         * @param {Map}
599         *            user options
600         * @return an error string if validation failed
601         */
602        _equals: function(field, rules, i, options) {
603            var equalsField = rules[i + 1];
604			
605            if (field.val() != $("#" + equalsField).val())
606                return options.allrules.equals.alertText;
607        },
608        /**
609         * Check the maximum size (in characters)
610         *
611         * @param {jqObject} field
612         * @param {Array[String]} rules
613         * @param {int} i rules index
614         * @param {Map}
615         *            user options
616         * @return an error string if validation failed
617         */
618        _maxSize: function(field, rules, i, options) {
619            var max = rules[i + 1];
620            var len = field.val().length;
621
622            if (len > max) {
623                var rule = options.allrules.maxSize;
624                return rule.alertText + max + rule.alertText2;
625            }
626        },
627        /**
628         * Check the minimum size (in characters)
629         *
630         * @param {jqObject} field
631         * @param {Array[String]} rules
632         * @param {int} i rules index
633         * @param {Map}
634         *            user options
635         * @return an error string if validation failed
636         */
637        _minSize: function(field, rules, i, options) {
638            var min = rules[i + 1];
639            var len = field.val().length;
640
641            if (len < min) {
642                var rule = options.allrules.minSize;
643                return rule.alertText + min + rule.alertText2;
644            }
645        },
646        /**
647         * Check number minimum value
648         *
649         * @param {jqObject} field
650         * @param {Array[String]} rules
651         * @param {int} i rules index
652         * @param {Map}
653         *            user options
654         * @return an error string if validation failed
655         */
656        _min: function(field, rules, i, options) {
657            var min = parseFloat(rules[i + 1]);
658            var len = parseFloat(field.val());
659
660            if (len < min) {
661                var rule = options.allrules.min;
662                if (rule.alertText2) return rule.alertText + min + rule.alertText2;
663                return rule.alertText + min;
664            }
665        },
666        /**
667         * Check number maximum value
668         *
669         * @param {jqObject} field
670         * @param {Array[String]} rules
671         * @param {int} i rules index
672         * @param {Map}
673         *            user options
674         * @return an error string if validation failed
675         */
676        _max: function(field, rules, i, options) {
677            var max = parseFloat(rules[i + 1]);
678            var len = parseFloat(field.val());
679
680            if (len >max ) {
681                var rule = options.allrules.max;
682                if (rule.alertText2) return rule.alertText + max + rule.alertText2;
683                //orefalo: to review, also do the translations
684                return rule.alertText + max;
685            }
686        },
687        /**
688         * Checks date is in the past
689         *
690         * @param {jqObject} field
691         * @param {Array[String]} rules
692         * @param {int} i rules index
693         * @param {Map}
694         *            user options
695         * @return an error string if validation failed
696         */
697        _past: function(field, rules, i, options) {
698
699            var p=rules[i + 1];
700            var pdate = (p.toLowerCase() == "now")? new Date():methods._parseDate(p);
701            var vdate = methods._parseDate(field.val());
702
703            if (vdate < pdate ) {
704                var rule = options.allrules.past;
705                if (rule.alertText2) return rule.alertText + methods._dateToString(pdate) + rule.alertText2;
706                return rule.alertText + methods._dateToString(pdate);
707            }
708        },
709        /**
710         * Checks date is in the future
711         *
712         * @param {jqObject} field
713         * @param {Array[String]} rules
714         * @param {int} i rules index
715         * @param {Map}
716         *            user options
717         * @return an error string if validation failed
718         */
719        _future: function(field, rules, i, options) {
720
721            var p=rules[i + 1];
722            var pdate = (p.toLowerCase() == "now")? new Date():methods._parseDate(p);
723            var vdate = methods._parseDate(field.val());
724
725            if (vdate > pdate ) {
726                var rule = options.allrules.future;
727                if (rule.alertText2) return rule.alertText + methods._dateToString(pdate) + rule.alertText2;
728                return rule.alertText + methods._dateToString(pdate);
729            }
730        },
731        /**
732         * Max number of checkbox selected
733         *
734         * @param {jqObject} field
735         * @param {Array[String]} rules
736         * @param {int} i rules index
737         * @param {Map}
738         *            user options
739         * @return an error string if validation failed
740         */
741        _maxCheckbox: function(field, rules, i, options) {
742
743            var nbCheck = rules[i + 1];
744            var groupname = field.attr("name");
745            var groupSize = $("input[name='" + groupname + "']:checked").size();
746            if (groupSize > nbCheck) {
747                options.showArrow = false;
748                if (options.allrules.maxCheckbox.alertText2) return options.allrules.maxCheckbox.alertText + " " + nbCheck + " " + options.allrules.maxCheckbox.alertText2;
749                return options.allrules.maxCheckbox.alertText;
750            }
751        },
752        /**
753         * Min number of checkbox selected
754         *
755         * @param {jqObject} field
756         * @param {Array[String]} rules
757         * @param {int} i rules index
758         * @param {Map}
759         *            user options
760         * @return an error string if validation failed
761         */
762        _minCheckbox: function(field, rules, i, options) {
763
764            var nbCheck = rules[i + 1];
765            var groupname = field.attr("name");
766            var groupSize = $("input[name='" + groupname + "']:checked").size();
767            if (groupSize < nbCheck) {
768                options.showArrow = false;
769                return options.allrules.minCheckbox.alertText + " " + nbCheck + " " +
770                options.allrules.minCheckbox.alertText2;
771            }
772        },
773        /**
774         * Ajax field validation
775         *
776         * @param {jqObject} field
777         * @param {Array[String]} rules
778         * @param {int} i rules index
779         * @param {Map}
780         *            user options
781         * @return nothing! the ajax validator handles the prompts itself
782         */
783        _ajax: function(field, rules, i, options) {
784			
785			
786            var errorSelector = rules[i + 1];
787            var rule = options.allrules[errorSelector];
788            var extraData = rule.extraData;
789            var extraDataDynamic = rule.extraDataDynamic;
790
791            if (!extraData)
792                extraData = "";
793
794            if (extraDataDynamic) {
795              var tmpData = [];
796              var domIds = String(extraDataDynamic).split(",");
797              for (var i = 0; i < domIds.length; i++) {
798                var id = domIds[i];
799                if ($(id).length) {
800                  var inputValue = field.closest("form").find(id).val();
801                  var keyValue = id.replace('#', '') + '=' + escape(inputValue);
802                  tmpData.push(keyValue);
803                }
804              }
805              extraDataDynamic = tmpData.join("&");
806            } else {
807              extraDataDynamic = "";              
808            }
809                                
810            if (!options.isError) {
811                $.ajax({
812                    type: "POST",
813                    url: rule.url,
814                    cache: false,
815                    dataType: "json",
816                    data: "fieldId=" + field.attr("id") + "&fieldValue=" + field.val() + "&extraData=" + extraData + "&" + extraDataDynamic,
817                    field: field,
818                    rule: rule,
819                    methods: methods,
820                    options: options,
821                    beforeSend: function() {
822                        // build the loading prompt
823                        var loadingText = rule.alertTextLoad;
824                        if (loadingText)
825                            methods._showPrompt(field, loadingText, "load", true, options);
826                    },
827                    error: function(data, transport) {
828                        methods._ajaxError(data, transport);
829                    },
830                    success: function(json) { 
831						
832                        // asynchronously called on success, data is the json answer from the server
833						
834                        var errorFieldId = json[0];
835                        var errorField = $($("#" + errorFieldId)[0]);
836                        // make sure we found the element
837                        if (errorField.length == 1) {
838                            var status = json[1];
839							// read the optional msg from the server
840							var msg = json[2];
841                            if (!status) {
842                                // Houston we got a problem - display an red prompt
843                                options.ajaxValidCache[errorFieldId] = false;
844                                options.isError = true;
845
846								// resolve the msg prompt
847								if(msg) {
848									if (options.allrules[msg]) {
849                                    	var txt = options.allrules[msg].alertText;
850                                    	if (txt)
851                                    		msg = txt;
852                                    }
853								}
854								else
855                                    msg = rule.alertText;
856                                
857								methods._showPrompt(errorField, msg, "", false, options);
858								return msg;
859                            } else {
860                                if (options.ajaxValidCache[errorFieldId] !== undefined)
861                                    options.ajaxValidCache[errorFieldId] = true;
862
863                                // resolves the msg prompt
864								if(msg) {
865									if (options.allrules[msg]) {
866							           	var txt = options.allrules[msg].alertTextOk;
867							           	if (txt)
868							           		msg = txt;
869							        }
870								}
871								else
872							       	msg = rule.alertTextOk;                                
873
874								// see if we should display a green prompt
875                                if (msg)
876                                    methods._showPrompt(errorField, msg, "pass", true, options);
877                                else
878                                    methods._closePrompt(errorField);
879									
880								return msg;	
881                            }
882                        }
883						
884                    }
885                });
886            }
887        },
888        /**
889         * Common method to handle ajax errors
890         *
891         * @param {Object} data
892         * @param {Object} transport
893         */
894        _ajaxError: function(data, transport) {
895            if(data.status == 0 && transport == null)
896                alert("The page is not served from a server! ajax call failed");
897            else if(typeof console != "undefined")
898                console.log("Ajax error: " + data.status + " " + transport);
899        },
900        /**
901         * date -> string
902         *
903         * @param {Object} date
904         */
905        _dateToString: function(date) {
906
907            return date.getFullYear()+"-"+(date.getMonth()+1)+"-"+date.getDate();
908        },
909        /**
910         * Parses an ISO date
911         * @param {String} d
912         */
913        _parseDate: function(d) {
914
915            var dateParts = d.split("-");
916            if(dateParts==d)
917                dateParts = d.split("/");
918            return new Date(dateParts[0], (dateParts[1] - 1) ,dateParts[2]);
919        },
920        /**
921         * Builds or updates a prompt with the given information
922         *
923         * @param {jqObject} field
924         * @param {String} promptText html text to display type
925         * @param {String} type the type of bubble: 'pass' (green), 'load' (black) anything else (red)
926         * @param {boolean} ajaxed - use to mark fields than being validated with ajax
927         * @param {Map} options user options
928         */
929        _showPrompt: function(field, promptText, type, ajaxed, options, ajaxform) {
930            var prompt = methods._getPrompt(field);
931			// The ajax submit errors are not see has an error in the form,
932			// When the form errors are returned, the engine see 2 bubbles, but those are ebing closed by the engine at the same time
933			// Because no error was found befor submitting
934			if(ajaxform) prompt = false;
935            if (prompt)
936                methods._updatePrompt(field, prompt, promptText, type, ajaxed, options);
937            else
938                methods._buildPrompt(field, promptText, type, ajaxed, options);
939        },
940        /**
941         * Builds and shades a prompt for the given field.
942         *
943         * @param {jqObject} field
944         * @param {String} promptText html text to display type
945         * @param {String} type the type of bubble: 'pass' (green), 'load' (black) anything else (red)
946         * @param {boolean} ajaxed - use to mark fields than being validated with ajax
947         * @param {Map} options user options
948         */
949        _buildPrompt: function(field, promptText, type, ajaxed, options) {
950
951            // create the prompt
952            var prompt = $('<div>');
953            prompt.addClass(methods._getClassName(field.attr("id")) + "formError");
954            // add a class name to identify the parent form of the prompt
955            if(field.is(":input")) prompt.addClass("parentForm"+methods._getClassName(field.parents('form').attr("id")));
956            prompt.addClass("formError");
957
958            switch (type) {
959                case "pass":
960                    prompt.addClass("greenPopup");
961                    break;
962                case "load":
963                    prompt.addClass("blackPopup");
964            }
965            if (ajaxed)
966                prompt.addClass("ajaxed");
967
968            // create the prompt content
969            var promptContent = $('<div>').addClass("formErrorContent").html(promptText).appendTo(prompt);
970            // create the css arrow pointing at the field
971            // note that there is no triangle on max-checkbox and radio
972            if (options.showArrow) {
973                var arrow = $('<div>').addClass("formErrorArrow");
974
975                switch (options.promptPosition) {
976                    case "bottomLeft":
977                    case "bottomRight":
978                        prompt.find(".formErrorContent").before(arrow);
979                        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>');
980                        break;
981                    case "topLeft":
982                    case "topRight":
983                        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>');
984                        prompt.append(arrow);
985                        break;
986                }
987            }
988
989            //Cedric: Needed if a container is in position:relative
990            // insert prompt in the form or in the overflown container?
991            if (options.isOverflown)
992            	field.before(prompt);
993            else
994               $("body").append(prompt);
995
996            var pos = methods._calculatePosition(field, prompt, options);
997            prompt.css({
998                "top": pos.callerTopPosition,
999                "left": pos.callerleftPosition,
1000                "marginTop": pos.marginTopSize,
1001                "opacity": 0
1002            });
1003
1004            return prompt.animate({
1005                "opacity": 0.87
1006            });
1007
1008        },
1009        /**
1010         * Updates the prompt text field - the field for which the prompt
1011         * @param {jqObject} field
1012         * @param {String} promptText html text to display type
1013         * @param {String} type the type of bubble: 'pass' (green), 'load' (black) anything else (red)
1014         * @param {boolean} ajaxed - use to mark fields than being validated with ajax
1015         * @param {Map} options user options
1016         */
1017        _updatePrompt: function(field, prompt, promptText, type, ajaxed, options) {
1018			
1019            if (prompt) {
1020                if (type == "pass")
1021                    prompt.addClass("greenPopup");
1022                else
1023                    prompt.removeClass("greenPopup");
1024
1025                if (type == "load")
1026                    prompt.addClass("blackPopup");
1027                else
1028                    prompt.removeClass("blackPopup");
1029
1030                if (ajaxed)
1031                    prompt.addClass("ajaxed");
1032                else
1033                    prompt.removeClass("ajaxed");
1034
1035                prompt.find(".formErrorContent").html(promptText);
1036
1037                var pos = methods._calculatePosition(field, prompt, options);
1038                prompt.animate({
1039                    "top": pos.callerTopPosition,
1040                    "marginTop": pos.marginTopSize
1041                });
1042            }
1043        },
1044        /**
1045         * Closes the prompt associated with the given field
1046         *
1047         * @param {jqObject}
1048         *            field
1049         */
1050        _closePrompt: function(field) {
1051
1052            var prompt = methods._getPrompt(field);
1053            if (prompt)
1054                prompt.fadeTo("fast", 0, function() {
1055                    prompt.remove();
1056                });
1057        },
1058        closePrompt: function(field) {
1059            return methods._closePrompt(field);
1060        },
1061        /**
1062         * Returns the error prompt matching the field if any
1063         *
1064         * @param {jqObject}
1065         *            field
1066         * @return undefined or the error prompt (jqObject)
1067         */
1068        _getPrompt: function(field) {
1069
1070            var className = "." + methods._getClassName(field.attr("id")) + "formError";
1071            var match = $(className)[0];
1072            if (match)
1073                return $(match);
1074        },
1075        /**
1076         * Calculates prompt position
1077         *
1078         * @param {jqObject}
1079         *            field
1080         * @param {jqObject}
1081         *            the prompt
1082         * @param {Map}
1083         *            options
1084         * @return positions
1085         */
1086        _calculatePosition: function(field, promptElmt, options) {
1087
1088            var promptTopPosition, promptleftPosition, marginTopSize;
1089            var fieldWidth = field.width();
1090            var promptHeight = promptElmt.height();
1091
1092            var overflow = options.isOverflown;
1093            if (overflow) {
1094                // is the form contained in an overflown container?
1095                promptTopPosition = promptleftPosition = 0;
1096                // compensation for the arrow
1097                marginTopSize = -promptHeight;
1098            } else {
1099                var offset = field.offset();
1100                promptTopPosition = offset.top;
1101                promptleftPosition = offset.left;
1102                marginTopSize = 0;
1103            }
1104
1105            switch (options.promptPosition) {
1106
1107                default:
1108                case "topRight":
1109                    if (overflow)
1110                        // Is the form contained in an overflown container?
1111                        promptleftPosition += fieldWidth - 30;
1112                    else {
1113                        promptleftPosition += fieldWidth - 30;
1114                        promptTopPosition += -promptHeight;
1115                    }
1116                    break;
1117                case "topLeft":
1118                    promptTopPosition += -promptHeight - 10;
1119                    break;
1120                case "centerRight":
1121                    promptleftPosition += fieldWidth + 13;
1122                    break;
1123                case "bottomLeft":
1124                    promptTopPosition = promptTopPosition + field.height() + 15;
1125                    break;
1126                case "bottomRight":
1127                    promptleftPosition += fieldWidth - 30;
1128                    promptTopPosition += field.height() + 5;
1129            }
1130
1131            return {
1132                "callerTopPosition": promptTopPosition + "px",
1133                "callerleftPosition": promptleftPosition + "px",
1134                "marginTopSize": marginTopSize + "px"
1135            };
1136        },
1137        /**
1138         * Saves the user options and variables in the form.data
1139         *
1140         * @param {jqObject}
1141         *            form - the form where the user option should be saved
1142         * @param {Map}
1143         *            options - the user options
1144         * @return the user options (extended from the defaults)
1145         */
1146        _saveOptions: function(form, options) {
1147
1148            // is there a language localisation ?
1149            if ($.validationEngineLanguage)
1150                var allRules = $.validationEngineLanguage.allRules;
1151            else
1152                $.error("jQuery.validationEngine rules are not loaded, plz add localization files to the page");
1153
1154            var userOptions = $.extend({
1155
1156                // Name of the event triggering field validation
1157                validationEventTrigger: "blur",
1158                // Automatically scroll viewport to the first error
1159                scroll: true,
1160                // Opening box position, possible locations are: topLeft,
1161                // topRight, bottomLeft, centerRight, bottomRight
1162                promptPosition: "topRight",
1163                bindMethod:"bind",
1164				// internal, automatically set to true when it parse a _ajax rule
1165				inlineAjax: false,
1166                // if set to true, the form data is sent asynchronously via ajax to the form.action url (get)
1167                ajaxFormValidation: false,
1168                // Ajax form validation callback method: boolean onComplete(form, status, errors, options)
1169                // retuns false if the form.submit event needs to be canceled.
1170				ajaxFormValidationURL: false,
1171                // The url to send the submit ajax validation (default to action)
1172                onAjaxFormComplete: $.noop,
1173                // called right before the ajax call, may return false to cancel
1174                onBeforeAjaxFormValidation: $.noop,
1175                // Stops form from submitting and execute function assiciated with it
1176                onValidationComplete: false,
1177
1178                // Used when the form is displayed within a scrolling DIV
1179                isOverflown: false,
1180                overflownDIV: "",
1181
1182                // --- Internals DO NOT TOUCH or OVERLOAD ---
1183                // validation rules and i18
1184                allrules: allRules,
1185                // true when form and fields are binded
1186                binded: false,
1187                // set to true, when the prompt arrow needs to be displayed
1188                showArrow: true,
1189                // did one of the validation fail ? kept global to stop further ajax validations
1190                isError: false,
1191                // Caches field validation status, typically only bad status are created.
1192                // the array is used during ajax form validation to detect issues early and prevent an expensive submit
1193                ajaxValidCache: {}
1194
1195            }, options);
1196
1197            form.data('jqv', userOptions);
1198            return userOptions;
1199        },
1200        
1201        /**
1202         * Removes forbidden characters from class name
1203         * @param {String} className
1204         */
1205        _getClassName: function(className) {
1206        	return className.replace(":","_").replace(".","_");
1207        }
1208    };
1209
1210    /**
1211     * Plugin entry point.
1212     * You may pass an action as a parameter or a list of options.
1213     * if none, the init and attach methods are being called.
1214     * Remember: if you pass options, the attached method is NOT called automatically
1215     *
1216     * @param {String}
1217     *            method (optional) action
1218     */
1219    $.fn.validationEngine = function(method) {
1220
1221        var form = $(this);
1222		  if(!form[0]) return false;  // stop here if the form does not exist
1223		  
1224        if (typeof(method) == 'string' && method.charAt(0) != '_' && methods[method]) {
1225
1226            // make sure init is called once
1227            if(method != "showPrompt" && method != "hidePrompt" && method != "hide" && method != "hideAll") 
1228            	methods.init.apply(form);
1229             
1230            return methods[method].apply(form, Array.prototype.slice.call(arguments, 1));
1231        } else if (typeof method == 'object' || !method) {
1232            // default constructor with or without arguments
1233			methods.init.apply(form, arguments);
1234            return methods.attach.apply(form);
1235        } else {
1236            $.error('Method ' + method + ' does not exist in jQuery.validationEngine');
1237        }
1238    };
1239})(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.