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