PageSourceSearch

https://www.sophiegajan.com/js/jquery.validationEngine.js

js sophiegajan.com collected 2026-10-08 09:01:56 UTC 48,280 bytes, 1,184 lines download raw bytes

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

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.