1/*! 2 * Fabrique D'Images ebusiness GmbH (FDI) Validation Plugin v0.1.0 3 * 4 * includes: 5 * - jQuery Validation Plugin v1.14.0 6 * - modified for div-Container-Support (like https://github.com/jzaefferer/jquery-validation/pull/452/files) 7 * - added FDI-voila Captcha-Support 8 * - added German text-snippets (from http://ajax.aspnetcdn.com/ajax/jquery.validate/1.14.0/localization/messages_de.js) 9 * 10 * by Sergej Kutschin 11 * Copyright (c) 2015 Fabrique D'Images ebusiness GmbH 12 * Released under the MIT license 13 * 14 * 15 * jQuery Validation Plugin v1.14.0: 16 *** http://jqueryvalidation.org/ 17 *** 18 *** Copyright (c) 2015 Jörn Zaefferer 19 *** Released under the MIT license 20 */ 21(function (factory) { 22 if (typeof define === "function" && define.amd) { 23 define(["jquery"], factory); 24 } else { 25 factory(jQuery); 26 } 27}(function ($) { 28 29 $.extend($.fn, { 30 // http://jqueryvalidation.org/validate/ 31 validate: function (options) { 32 33 // if nothing is selected, return nothing; can't chain anyway 34 if (!this.length) { 35 if (options && options.debug && window.console) { 36 console.warn("Nothing selected, can't validate, returning nothing."); 37 } 38 return; 39 } 40 41 // check if a validator for this form was already created 42 var validator = $.data(this[0], "validator"); 43 if (validator) { 44 return validator; 45 } 46 47 // Add novalidate tag if HTML5. 48 this.attr("novalidate", "novalidate"); 49 50 validator = new $.validator(options, this[0]); 51 $.data(this[0], "validator", validator); 52 53 if (validator.settings.onsubmit) { 54 55 this.on("click.validate", ":submit", function (event) { 56 if (validator.settings.submitHandler) { 57 validator.submitButton = event.target; 58 } 59 60 // allow suppressing validation by adding a cancel class to the submit button 61 if ($(this).hasClass("cancel")) { 62 validator.cancelSubmit = true; 63 } 64 65 // allow suppressing validation by adding the html5 formnovalidate attribute to the submit button 66 if ($(this).attr("formnovalidate") !== undefined) { 67 validator.cancelSubmit = true; 68 } 69 }); 70 71 // validate the form on submit 72 this.on("submit.validate", function (event) { 73 if (validator.settings.debug) { 74 // prevent form submit to be able to see console output 75 event.preventDefault(); 76 } 77 78 function handle() { 79 var hidden, result; 80 if (validator.settings.submitHandler) { 81 if (validator.submitButton) { 82 // insert a hidden input as a replacement for the missing submit button 83 hidden = $("<input type='hidden'/>") 84 .attr("name", validator.submitButton.name) 85 .val($(validator.submitButton).val()) 86 .appendTo(validator.currentForm); 87 } 88 result = validator.settings.submitHandler.call(validator, validator.currentForm, event); 89 if (validator.submitButton) { 90 // and clean up afterwards; thanks to no-block-scope, hidden can be referenced 91 hidden.remove(); 92 } 93 if (result !== undefined) { 94 return result; 95 } 96 return false; 97 } 98 return true; 99 } 100 101 // prevent submit for invalid forms or custom submit handlers 102 if (validator.cancelSubmit) { 103 validator.cancelSubmit = false; 104 return handle(); 105 } 106 if (validator.form()) { 107 if (validator.pendingRequest) { 108 validator.formSubmitted = true; 109 return false; 110 } 111 return handle(); 112 } else { 113 validator.focusInvalid(); 114 return false; 115 } 116 }); 117 } 118 119 return validator; 120 }, 121 // http://jqueryvalidation.org/valid/ 122 valid: function () { 123 var valid, validator, errorList; 124 125 if ($(this[0]).is("form")) { 126 valid = this.validate().form(); 127 } else { 128 errorList = []; 129 valid = true; 130 validator = $(this[0].form).validate(); 131 this.each(function () { 132 valid = validator.element(this) && valid; 133 errorList = errorList.concat(validator.errorList); 134 }); 135 validator.errorList = errorList; 136 } 137 return valid; 138 }, 139 140 // http://jqueryvalidation.org/rules/ 141 rules: function (command, argument) { 142 var element = this[0], 143 settings, staticRules, existingRules, data, param, filtered; 144 145 if (command) { 146 settings = $.data(element.form, "validator").settings; 147 staticRules = settings.rules;
148 existingRules = $.validator.staticRules(element); 149 switch (command) { 150 case "add": 151 $.extend(existingRules, $.validator.normalizeRule(argument)); 152 // remove messages from rules, but allow them to be set separately 153 delete existingRules.messages; 154 staticRules[element.name] = existingRules; 155 if (argument.messages) { 156 settings.messages[element.name] = $.extend(settings.messages[element.name], argument.messages); 157 } 158 break; 159 case "remove": 160 if (!argument) { 161 delete staticRules[element.name]; 162 return existingRules; 163 } 164 filtered = {}; 165 $.each(argument.split(/\s/), function (index, method) { 166 filtered[method] = existingRules[method]; 167 delete existingRules[method]; 168 if (method === "required") { 169 $(element).removeAttr("aria-required"); 170 } 171 }); 172 return filtered; 173 } 174 } 175 176 data = $.validator.normalizeRules( 177 $.extend({}, 178 $.validator.classRules(element), 179 $.validator.attributeRules(element), 180 $.validator.dataRules(element), 181 $.validator.staticRules(element) 182 ), element); 183 184 // make sure required is at front 185 if (data.required) { 186 param = data.required; 187 delete data.required; 188 data = $.extend({ 189 required: param 190 }, data); 191 $(element).attr("aria-required", "true"); 192 } 193 194 // make sure remote is at back 195 if (data.remote) { 196 param = data.remote; 197 delete data.remote; 198 data = $.extend(data, { 199 remote: param 200 }); 201 } 202 203 return data; 204 } 205 }); 206 207 // Custom selectors 208 $.extend($.expr[":"], { 209 // http://jqueryvalidation.org/blank-selector/ 210 blank: function (a) { 211 return !$.trim("" + $(a).val()); 212 }, 213 // http://jqueryvalidation.org/filled-selector/ 214 filled: function (a) { 215 return !!$.trim("" + $(a).val()); 216 }, 217 // http://jqueryvalidation.org/unchecked-selector/ 218 unchecked: function (a) { 219 return !$(a).prop("checked"); 220 } 221 }); 222 223 // constructor for validator 224 $.validator = function (options, form) { 225 this.settings = $.extend(true, {}, $.validator.defaults, options); 226 this.currentForm = form; 227 this.init(); 228 }; 229 230 // http://jqueryvalidation.org/jQuery.validator.format/ 231 $.validator.format = function (source, params) { 232 if (arguments.length === 1) { 233 return function () { 234 var args = $.makeArray(arguments); 235 args.unshift(source); 236 return $.validator.format.apply(this, args); 237 }; 238 } 239 if (arguments.length > 2 && params.constructor !== Array) { 240 params = $.makeArray(arguments).slice(1); 241 } 242 if (params.constructor !== Array) { 243 params = [params]; 244 } 245 $.each(params, function (i, n) { 246 source = source.replace(new RegExp("\\{" + i + "\\}", "g"), function () { 247 return n; 248 }); 249 }); 250 return source; 251 }; 252 253 $.extend($.validator, { 254 255 defaults: { 256 messages: {}, 257 groups: {}, 258 rules: {}, 259 errorClass: "error", 260 validClass: "valid", 261 errorElement: "label", 262 focusCleanup: false, 263 focusInvalid: true, 264 errorContainer: $([]), 265 errorLabelContainer: $([]), 266 onsubmit: true, 267 ignore: ":hidden", 268 ignoreTitle: false, 269 onfocusin: function (element) { 270 this.lastActive = element; 271 272 // Hide error label and remove error class on focus if enabled 273 if (this.settings.focusCleanup) { 274 if (this.settings.unhighlight) { 275 this.settings.unhighlight.call(this, element, this.settings.errorClass, this.settings.validClass); 276 } 277 this.hideThese(this.errorsFor(element)); 278 } 279 }, 280 onfocusout: function (element) { 281 if (!this.checkable(element) && (element.name in this.submitted || !this.optional(element))) { 282 this.element(element); 283 } 284 }, 285 onkeyup: function (element, event) { 286 // Avoid revalidate the field when pressing one of the following keys 287 // Shift => 16 288 // Ctrl => 17 289 // Alt => 18 290 // Caps lock => 20 291 // End => 35 292 // Home => 36 293 // Left arrow => 37 294 // Up arrow => 38 295 // Right arrow => 39 296 // Down arrow => 40 297 // Insert => 45 298 // Num lock => 144 299 // AltGr key => 225 300 var excludedKeys = [ 301 16, 17, 18, 20, 35, 36, 37, 302 38, 39, 40, 45, 144, 225 303 ]; 304 305 if (event.which === 9 && this.elementValue(element) === "" || $.inArray(event.keyCode, excludedKeys) !== -1) { 306 return; 307 } else if (element.name in this.submitted || element === this.lastElement) {
308 this.element(element); 309 } 310 }, 311 onclick: function (element) { 312 // click on selects, radiobuttons and checkboxes 313 if (element.name in this.submitted) { 314 this.element(element); 315 316 // or option elements, check parent select in that case 317 } else if (element.parentNode.name in this.submitted) { 318 this.element(element.parentNode); 319 } 320 }, 321 highlight: function (element, errorClass, validClass) { 322 if (element.type === "radio") { 323 this.findByName(element.name).addClass(errorClass).removeClass(validClass); 324 } else { 325 $(element).addClass(errorClass).removeClass(validClass); 326 } 327 }, 328 unhighlight: function (element, errorClass, validClass) { 329 if (element.type === "radio") { 330 this.findByName(element.name).removeClass(errorClass).addClass(validClass); 331 } else { 332 $(element).removeClass(errorClass).addClass(validClass); 333 } 334 } 335 }, 336 337 // http://jqueryvalidation.org/jQuery.validator.setDefaults/ 338 setDefaults: function (settings) { 339 $.extend($.validator.defaults, settings); 340 }, 341 342 messages: { 343 required: "This field is required.", 344 remote: "Please fix this field.", 345 email: "Please enter a valid email address.", 346 url: "Please enter a valid URL.", 347 date: "Please enter a valid date.", 348 dateISO: "Please enter a valid date ( ISO ).", 349 number: "Please enter a valid number.", 350 digits: "Please enter only digits.", 351 creditcard: "Please enter a valid credit card number.", 352 equalTo: "Please enter the same value again.", 353 maxlength: $.validator.format("Please enter no more than {0} characters."), 354 minlength: $.validator.format("Please enter at least {0} characters."), 355 rangelength: $.validator.format("Please enter a value between {0} and {1} characters long."), 356 range: $.validator.format("Please enter a value between {0} and {1}."), 357 max: $.validator.format("Please enter a value less than or equal to {0}."), 358 min: $.validator.format("Please enter a value greater than or equal to {0}.") 359 }, 360 361 autoCreateRanges: false, 362 363 prototype: { 364 365 init: function () { 366 this.labelContainer = $(this.settings.errorLabelContainer); 367 this.errorContext = this.labelContainer.length && this.labelContainer || $(this.currentForm); 368 this.containers = $(this.settings.errorContainer).add(this.settings.errorLabelContainer); 369 this.submitted = {}; 370 this.valueCache = {}; 371 this.pendingRequest = 0; 372 this.pending = {}; 373 this.invalid = {}; 374 this.reset(); 375 376 var groups = (this.groups = {}), 377 rules; 378 $.each(this.settings.groups, function (key, value) { 379 if (typeof value === "string") { 380 value = value.split(/\s/); 381 } 382 $.each(value, function (index, name) { 383 groups[name] = key; 384 }); 385 }); 386 rules = this.settings.rules; 387 $.each(rules, function (key, value) { 388 rules[key] = $.validator.normalizeRule(value); 389 }); 390 391 function delegate(event) { 392 var validator = $.data(this.form, "validator"), 393 eventType = "on" + event.type.replace(/^validate/, ""), 394 settings = validator.settings; 395 if (settings[eventType] && !$(this).is(settings.ignore)) { 396 settings[eventType].call(validator, this, event); 397 } 398 } 399 400 $(this.currentForm) 401 .on("focusin.validate focusout.validate keyup.validate", 402 ":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'], " + 403 "[type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], " + 404 "[type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'], " + 405 "[type='radio'], [type='checkbox']", delegate) 406 // Support: Chrome, oldIE 407 // "select" is provided as event.target when clicking a option 408 .on("click.validate", "select, option, [type='radio'], [type='checkbox']", delegate); 409 410 if (this.settings.invalidHandler) { 411 $(this.currentForm).on("invalid-form.validate", this.settings.invalidHandler); 412 } 413 414 // Add aria-required to any Static/Data/Class required fields before first validation 415 // Screen readers require this attribute to be present before the initial submission http://www.w3.org/TR/WCAG-TECHS/ARIA2.html 416 $(this.currentForm).find("[required], [data-rule-required], .required").attr("aria-required", "true"); 417 }, 418 419 // http://jqueryvalidation.org/Validator.form/ 420 form: function (container) { 421 this.checkForm(container); 422 $.extend(this.submitted, this.errorMap); 423 this.invalid = $.extend({}, this.errorMap); 424 if (!this.valid()) { 425 $(this.currentForm).triggerHandler("invalid-form", [this]); 426 } 427 this.showErrors(); 428 return this.valid(); 429 }, 430 431 checkForm: function (container) { 432 this.prepareForm(); 433 for (var i = 0, elements = (this.currentElements = this.elements(container)); elements[i]; i++) { 434 this.check(elements[i]); 435 } 436 return this.valid(); 437 }, 438 439 // http://jqueryvalidation.org/Validator.element/ 440 element: function (element) { 441 var cleanElement = this.clean(element), 442 checkElement = this.validationTargetFor(cleanElement), 443 result = true; 444 445 this.lastElement = checkElement; 446 447 if (checkElement === undefined) { 448 delete this.invalid[cleanElement.name]; 449 } else { 450 this.prepareElement(checkElement); 451 this.currentElements = $(checkElement); 452 453 result = this.check(checkElement) !== false; 454 if (result) { 455 delete this.invalid[checkElement.name]; 456 } else { 457 this.invalid[checkElement.name] = true; 458 } 459 } 460 // Add aria-invalid status for screen readers 461 $(element).attr("aria-invalid", !result); 462 463 if (!this.numberOfInvalids()) { 464 // Hide error containers on last error
465 this.toHide = this.toHide.add(this.containers); 466 } 467 this.showErrors(); 468 return result; 469 }, 470 471 // http://jqueryvalidation.org/Validator.showErrors/ 472 showErrors: function (errors) { 473 if (errors) { 474 // add items to error list and map 475 $.extend(this.errorMap, errors); 476 this.errorList = []; 477 for (var name in errors) { 478 this.errorList.push({ 479 message: errors[name], 480 element: this.findByName(name)[0] 481 }); 482 } 483 // remove items from success list 484 this.successList = $.grep(this.successList, function (element) { 485 return !(element.name in errors); 486 }); 487 } 488 if (this.settings.showErrors) { 489 this.settings.showErrors.call(this, this.errorMap, this.errorList); 490 } else { 491 this.defaultShowErrors(); 492 } 493 }, 494 495 // http://jqueryvalidation.org/Validator.resetForm/ 496 resetForm: function () { 497 if ($.fn.resetForm) { 498 $(this.currentForm).resetForm(); 499 } 500 this.submitted = {}; 501 this.lastElement = null; 502 this.prepareForm(); 503 this.hideErrors(); 504 var i, elements = this.elements() 505 .removeData("previousValue") 506 .removeAttr("aria-invalid"); 507 508 if (this.settings.unhighlight) { 509 for (i = 0; elements[i]; i++) { 510 this.settings.unhighlight.call(this, elements[i], 511 this.settings.errorClass, ""); 512 } 513 } else { 514 elements.removeClass(this.settings.errorClass); 515 } 516 }, 517 518 numberOfInvalids: function () { 519 return this.objectLength(this.invalid); 520 }, 521 522 objectLength: function (obj) { 523 /* jshint unused: false */ 524 var count = 0, 525 i; 526 for (i in obj) { 527 count++; 528 } 529 return count; 530 }, 531 532 hideErrors: function () { 533 this.hideThese(this.toHide); 534 }, 535 536 hideThese: function (errors) { 537 errors.not(this.containers).text(""); 538 this.addWrapper(errors).hide(); 539 }, 540 541 valid: function () { 542 return this.size() === 0; 543 }, 544 545 size: function () { 546 return this.errorList.length; 547 }, 548 549 focusInvalid: function () { 550 if (this.settings.focusInvalid) { 551 try { 552 $(this.findLastActive() || this.errorList.length && this.errorList[0].element || []) 553 .filter(":visible") 554 .focus() 555 // manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find 556 .trigger("focusin"); 557 } catch (e) { 558 // ignore IE throwing errors when focusing hidden elements 559 } 560 } 561 }, 562 563 findLastActive: function () { 564 var lastActive = this.lastActive; 565 return lastActive && $.grep(this.errorList, function (n) { 566 return n.element.name === lastActive.name; 567 }).length === 1 && lastActive; 568 }, 569 570 elements: function (container) { 571 container = container || $(this.currentForm); 572 var validator = this, 573 rulesCache = {}; 574 575 // select all valid inputs inside the form (no submit or reset buttons) 576 return container 577 .find("input, select, textarea") 578 .not(":submit, :reset, :image, :disabled") 579 .not(this.settings.ignore) 580 .filter(function () { 581 if (!this.name && validator.settings.debug && window.console) { 582 console.error("%o has no name assigned", this); 583 } 584 585 // select only the first element for each name, and only those with rules specified 586 if (this.name in rulesCache || !validator.objectLength($(this).rules())) { 587 return false; 588 } 589 590 rulesCache[this.name] = true; 591 return true; 592 }); 593 }, 594 595 clean: function (selector) { 596 return $(selector)[0]; 597 }, 598 599 errors: function () { 600 var errorClass = this.settings.errorClass.split(" ").join("."); 601 return $(this.settings.errorElement + "." + errorClass, this.errorContext); 602 }, 603 604 reset: function () { 605 this.successList = []; 606 this.errorList = []; 607 this.errorMap = {}; 608 this.toShow = $([]); 609 this.toHide = $([]); 610 this.currentElements = $([]); 611 }, 612 613 prepareForm: function () { 614 this.reset();
615 this.toHide = this.errors().add(this.containers); 616 }, 617 618 prepareElement: function (element) { 619 this.reset(); 620 this.toHide = this.errorsFor(element); 621 }, 622 623 elementValue: function (element) { 624 var val, 625 $element = $(element), 626 type = element.type; 627 628 if (type === "radio" || type === "checkbox") { 629 return this.findByName(element.name).filter(":checked").val(); 630 } else if (type === "number" && typeof element.validity !== "undefined") { 631 return element.validity.badInput ? false : $element.val(); 632 } 633 634 val = $element.val(); 635 if (typeof val === "string") { 636 return val.replace(/\r/g, ""); 637 } 638 return val; 639 }, 640 641 check: function (element) { 642 element = this.validationTargetFor(this.clean(element)); 643 644 var rules = $(element).rules(), 645 rulesCount = $.map(rules, function (n, i) { 646 return i; 647 }).length, 648 dependencyMismatch = false, 649 val = this.elementValue(element), 650 result, method, rule; 651 652 for (method in rules) { 653 rule = { 654 method: method, 655 parameters: rules[method] 656 }; 657 try { 658 659 result = $.validator.methods[method].call(this, val, element, rule.parameters); 660 661 // if a method indicates that the field is optional and therefore valid, 662 // don't mark it as valid when there are no other rules 663 if (result === "dependency-mismatch" && rulesCount === 1) { 664 dependencyMismatch = true; 665 continue; 666 } 667 dependencyMismatch = false; 668 669 if (result === "pending") { 670 this.toHide = this.toHide.not(this.errorsFor(element)); 671 return; 672 } 673 674 if (!result) { 675 this.formatAndAdd(element, rule); 676 return false; 677 } 678 } catch (e) { 679 if (this.settings.debug && window.console) { 680 console.log("Exception occurred when checking element " + element.id + ", check the '" + rule.method + "' method.", e); 681 } 682 if (e instanceof TypeError) { 683 e.message += ". Exception occurred when checking element " + element.id + ", check the '" + rule.method + "' method."; 684 } 685 686 throw e; 687 } 688 } 689 if (dependencyMismatch) { 690 return; 691 } 692 if (this.objectLength(rules)) { 693 this.successList.push(element); 694 } 695 return true; 696 }, 697 698 // return the custom message for the given element and validation method 699 // specified in the element's HTML5 data attribute 700 // return the generic message if present and no method specific message is present 701 customDataMessage: function (element, method) { 702 return $(element).data("msg" + method.charAt(0).toUpperCase() + 703 method.substring(1).toLowerCase()) || $(element).data("msg"); 704 }, 705 706 // return the custom message for the given element name and validation method 707 customMessage: function (name, method) { 708 var m = this.settings.messages[name]; 709 return m && (m.constructor === String ? m : m[method]); 710 }, 711 712 // return the first defined argument, allowing empty strings 713 findDefined: function () { 714 for (var i = 0; i < arguments.length; i++) { 715 if (arguments[i] !== undefined) { 716 return arguments[i]; 717 } 718 } 719 return undefined; 720 }, 721 722 defaultMessage: function (element, method) { 723 return this.findDefined( 724 this.customMessage(element.name, method), 725 this.customDataMessage(element, method), 726 // title is never undefined, so handle empty string as undefined 727 !this.settings.ignoreTitle && element.title || undefined, 728 $.validator.messages[method], 729 "<strong>Warning: No message defined for " + element.name + "</strong>" 730 ); 731 }, 732 733 formatAndAdd: function (element, rule) { 734 var message = this.defaultMessage(element, rule.method), 735 theregex = /\$?\{(\d+)\}/g; 736 if (typeof message === "function") { 737 message = message.call(this, rule.parameters, element); 738 } else if (theregex.test(message)) { 739 message = $.validator.format(message.replace(theregex, "{$1}"), rule.parameters); 740 } 741 this.errorList.push({ 742 message: message, 743 element: element, 744 method: rule.method 745 }); 746 747 this.errorMap[element.name] = message; 748 this.submitted[element.name] = message; 749 }, 750 751 addWrapper: function (toToggle) { 752 if (this.settings.wrapper) { 753 toToggle = toToggle.add(toToggle.parent(this.settings.wrapper)); 754 } 755 return toToggle; 756 }, 757 758 defaultShowErrors: function () { 759 var i, elements, error; 760 for (i = 0; this.errorList[i]; i++) { 761 error = this.errorList[i]; 762 if (this.settings.highlight) { 763 this.settings.highlight.call(this, error.element, this.settings.errorClass, this.settings.val
763idClass); 764 } 765 this.showLabel(error.element, error.message); 766 } 767 if (this.errorList.length) { 768 this.toShow = this.toShow.add(this.containers); 769 } 770 if (this.settings.success) { 771 for (i = 0; this.successList[i]; i++) { 772 this.showLabel(this.successList[i]); 773 } 774 } 775 if (this.settings.unhighlight) { 776 for (i = 0, elements = this.validElements(); elements[i]; i++) { 777 this.settings.unhighlight.call(this, elements[i], this.settings.errorClass, this.settings.validClass); 778 } 779 } 780 this.toHide = this.toHide.not(this.toShow); 781 this.hideErrors(); 782 this.addWrapper(this.toShow).show(); 783 }, 784 785 validElements: function () { 786 return this.currentElements.not(this.invalidElements()); 787 }, 788 789 invalidElements: function () { 790 return $(this.errorList).map(function () { 791 return this.element; 792 }); 793 }, 794 795 showLabel: function (element, message) { 796 var place, group, errorID, 797 error = this.errorsFor(element), 798 elementID = this.idOrName(element), 799 describedBy = $(element).attr("aria-describedby"); 800 if (error.length) { 801 // refresh error/success class 802 error.removeClass(this.settings.validClass).addClass(this.settings.errorClass); 803 // replace message on existing label 804 error.html(message); 805 } else { 806 // create error element 807 error = $("<" + this.settings.errorElement + ">") 808 .attr("id", elementID + "-error") 809 .addClass(this.settings.errorClass) 810 .html(message || ""); 811 812 // Maintain reference to the element to be placed into the DOM 813 place = error; 814 if (this.settings.wrapper) { 815 // make sure the element is visible, even in IE 816 // actually showing the wrapped element is handled elsewhere 817 place = error.hide().show().wrap("<" + this.settings.wrapper + "/>").parent(); 818 } 819 if (this.labelContainer.length) { 820 this.labelContainer.append(place); 821 } else if (this.settings.errorPlacement) { 822 this.settings.errorPlacement(place, $(element)); 823 } else { 824 place.insertAfter(element); 825 } 826 827 // Link error back to the element 828 if (error.is("label")) { 829 // If the error is a label, then associate using 'for' 830 error.attr("for", elementID); 831 } else if (error.parents("label[for='" + elementID + "']").length === 0) { 832 // If the element is not a child of an associated label, then it's necessary 833 // to explicitly apply aria-describedby 834 835 errorID = error.attr("id").replace(/(:|\.|\[|\]|\$)/g, "\\$1"); 836 // Respect existing non-error aria-describedby 837 if (!describedBy) { 838 describedBy = errorID; 839 } else if (!describedBy.match(new RegExp("\\b" + errorID + "\\b"))) { 840 // Add to end of list if not already present 841 describedBy += " " + errorID; 842 } 843 $(element).attr("aria-describedby", describedBy); 844 845 // If this element is grouped, then assign to all elements in the same group 846 group = this.groups[element.name]; 847 if (group) { 848 $.each(this.groups, function (name, testgroup) { 849 if (testgroup === group) { 850 $("[name='" + name + "']", this.currentForm) 851 .attr("aria-describedby", error.attr("id")); 852 } 853 }); 854 } 855 } 856 } 857 if (!message && this.settings.success) { 858 error.text(""); 859 if (typeof this.settings.success === "string") { 860 error.addClass(this.settings.success); 861 } else { 862 this.settings.success(error, element); 863 } 864 } 865 this.toShow = this.toShow.add(error); 866 }, 867 868 errorsFor: function (element) { 869 var name = this.idOrName(element), 870 describer = $(element).attr("aria-describedby"), 871 selector = "label[for='" + name + "'], label[for='" + name + "'] *"; 872 873 // aria-describedby should directly reference the error element 874 if (describer) { 875 selector = selector + ", #" + describer.replace(/\s+/g, ", #"); 876 } 877 return this 878 .errors() 879 .filter(selector); 880 }, 881 882 idOrName: function (element) { 883 return this.groups[element.name] || (this.checkable(element) ? element.name : element.i
vendor: 9,980 bytes, lines 883-1231
883d || element.name); 884 }, 885 886 validationTargetFor: function (element) { 887 888 // If radio/checkbox, validate first element in group instead 889 if (this.checkable(element)) { 890 element = this.findByName(element.name); 891 } 892 893 // Always apply ignore filter 894 return $(element).not(this.settings.ignore)[0]; 895 }, 896 897 checkable: function (element) { 898 return (/radio|checkbox/i).test(element.type); 899 }, 900 901 findByName: function (name) { 902 return $(this.currentForm).find("[name='" + name + "']"); 903 }, 904 905 getLength: function (value, element) { 906 switch (element.nodeName.toLowerCase()) { 907 case "select": 908 return $("option:selected", element).length; 909 case "input": 910 if (this.checkable(element)) { 911 return this.findByName(element.name).filter(":checked").length; 912 } 913 } 914 return value.length; 915 }, 916 917 depend: function (param, element) { 918 return this.dependTypes[typeof param] ? this.dependTypes[typeof param](param, element) : true; 919 }, 920 921 dependTypes: { 922 "boolean": function (param) { 923 return param; 924 }, 925 "string": function (param, element) { 926 return !!$(param, element.form).length; 927 }, 928 "function": function (param, element) { 929 return param(element); 930 } 931 }, 932 933 optional: function (element) { 934 var val = this.elementValue(element); 935 return !$.validator.methods.required.call(this, val, element) && "dependency-mismatch"; 936 }, 937 938 startRequest: function (element) { 939 if (!this.pending[element.name]) { 940 this.pendingRequest++; 941 this.pending[element.name] = true; 942 } 943 }, 944 945 stopRequest: function (element, valid) { 946 this.pendingRequest--; 947 // sometimes synchronization fails, make sure pendingRequest is never < 0 948 if (this.pendingRequest < 0) { 949 this.pendingRequest = 0; 950 } 951 delete this.pending[element.name]; 952 if (valid && this.pendingRequest === 0 && this.formSubmitted && this.form()) { 953 $(this.currentForm).submit(); 954 this.formSubmitted = false; 955 } else if (!valid && this.pendingRequest === 0 && this.formSubmitted) { 956 $(this.currentForm).triggerHandler("invalid-form", [this]); 957 this.formSubmitted = false; 958 } 959 }, 960 961 previousValue: function (element) { 962 return $.data(element, "previousValue") || $.data(element, "previousValue", { 963 old: null, 964 valid: true, 965 message: this.defaultMessage(element, "remote") 966 }); 967 }, 968 969 // cleans up all forms and elements, removes validator-specific events 970 destroy: function () { 971 this.resetForm(); 972 973 $(this.currentForm) 974 .off(".validate") 975 .removeData("validator"); 976 } 977 978 }, 979 980 classRuleSettings: { 981 required: { 982 required: true 983 }, 984 email: { 985 email: true 986 }, 987 url: { 988 url: true 989 }, 990 date: { 991 date: true 992 }, 993 dateISO: { 994 dateISO: true 995 }, 996 number: { 997 number: true 998 }, 999 digits: { 1000 digits: true 1001 }, 1002 creditcard: { 1003 creditcard: true 1004 } 1005 }, 1006 1007 addClassRules: function (className, rules) { 1008 if (className.constructor === String) { 1009 this.classRuleSettings[className] = rules; 1010 } else { 1011 $.extend(this.classRuleSettings, className); 1012 } 1013 }, 1014 1015 classRules: function (element) { 1016 var rules = {}, 1017 classes = $(element).attr("class"); 1018 1019 if (classes) { 1020 $.each(classes.split(" "), function () { 1021 if (this in $.validator.classRuleSettings) { 1022 $.extend(rules, $.validator.classRuleSettings[this]); 1023 } 1024 }); 1025 } 1026 return rules; 1027 }, 1028 1029 normalizeAttributeRule: function (rules, type, method, value) { 1030 1031 // convert the value to a number for number inputs, and for text for backwards compability 1032 // allows type="date" and others to be compared as strings 1033 if (/min|max/.test(method) && (type === null || /number|range|text/.test(type))) { 1034 value = Number(value); 1035 1036 // Support Opera Mini, which returns NaN for undefined minlength 1037 if (isNaN(value)) { 1038 value = undefined; 1039 } 1040 } 1041 1042 if (value || value === 0) { 1043 rules[method] = value; 1044 } else if (type === method && type !== "range") { 1045 1046 // exception: the jquery validate 'range' method 1047 // does not test for the html5 'range' type 1048 rules[method] = true; 1049 } 1050 }, 1051 1052 attributeRules: function (element) { 1053 var rules = {}, 1054 $element = $(element), 1055 type = element.getAttribute("type"), 1056 method, value; 1057 1058 for (method in $.validator.methods) { 1059 1060 // support for <input required> in both html5 and older browsers 1061 if (method === "required") { 1062 value = element.getAttribute(method); 1063 1064 // Some browsers return an empty string for the required attribute 1065 // and non-HTML5 browsers might have required="" markup 1066 if (value === "") { 1067 value = true; 1068 } 1069 1070 // force non-HTML5 browsers to return bool 1071 value = !!value; 1072 } else { 1073 value = $element.attr(method); 1074 } 1075 1076 this.normalizeAttributeRule(rules, type, method, value); 1077 } 1078 1079 // maxlength may be returned as -1, 2147483647 ( IE ) and 524288 ( safari ) for text inputs 1080 if (rules.maxlength && /-1|2147483647|524288/.test(rules.maxlength)) { 1081 delete rules.maxlength; 1082 } 1083 1084 return rules; 1085 }, 1086 1087 dataRules: function (element) { 1088 var rules = {}, 1089 $element = $(element), 1090 type = element.getAttribute("type"), 1091 method, value; 1092 1093 for (method in $.validator.methods) { 1094 value = $element.data("rule" + method.charAt(0).toUpperCase() + method.substring(1).toLowerCase()); 1095 this.normalizeAttributeRule(rules, type, method, value); 1096 } 1097 return rules; 1098 }, 1099 1100 staticRules: function (element) { 1101 var rules = {}, 1102 validator = $.data(element.form, "validator"); 1103 1104 if (validator.settings.rules) { 1105 rules = $.validator.normalizeRule(validator.settings.rules[element.name]) || {}; 1106 } 1107 return rules; 1108 }, 1109 1110 normalizeRules: function (rules, element) { 1111 // handle dependency check 1112 $.each(rules, function (prop, val) { 1113 // ignore rule when param is explicitly false, eg. required:false 1114 if (val === false) { 1115 delete rules[prop]; 1116 return; 1117 } 1118 if (val.param || val.depends) { 1119 var keepRule = true; 1120 switch (typeof val.depends) { 1121 case "string": 1122 keepRule = !!$(val.depends, element.form).length; 1123 break; 1124 case "function": 1125 keepRule = val.depends.call(element, element); 1126 break; 1127 } 1128 if (keepRule) { 1129 rules[prop] = val.param !== undefined ? val.param : true; 1130 } else { 1131 delete rules[prop]; 1132 } 1133 } 1134 }); 1135 1136 // evaluate parameters 1137 $.each(rules, function (rule, parameter) { 1138 rules[rule] = $.isFunction(parameter) ? parameter(element) : parameter; 1139 }); 1140 1141 // clean number parameters 1142 $.each(["minlength", "maxlength"], function () { 1143 if (rules[this]) { 1144 rules[this] = Number(rules[this]); 1145 } 1146 }); 1147 $.each(["rangelength", "range"], function () { 1148 var parts; 1149 if (rules[this]) { 1150 if ($.isArray(rules[this])) { 1151 rules[this] = [Number(rules[this][0]), Number(rules[this][1])]; 1152 } else if (typeof rules[this] === "string") { 1153 parts = rules[this].replace(/[\[\]]/g, "").split(/[\s,]+/); 1154 rules[this] = [Number(parts[0]), Number(parts[1])]; 1155 } 1156 } 1157 }); 1158 1159 if ($.validator.autoCreateRanges) { 1160 // auto-create ranges 1161 if (rules.min != null && rules.max != null) { 1162 rules.range = [rules.min, rules.max]; 1163 delete rules.min; 1164 delete rules.max; 1165 } 1166 if (rules.minlength != null && rules.maxlength != null) { 1167 rules.rangelength = [rules.minlength, rules.maxlength]; 1168 delete rules.minlength; 1169 delete rules.maxlength; 1170 } 1171 } 1172 1173 return rules; 1174 }, 1175 1176 // Converts a simple string to a {string: true} rule, e.g., "required" to {required:true} 1177 normalizeRule: function (data) { 1178 if (typeof data === "string") { 1179 var transformed = {}; 1180 $.each(data.split(/\s/), function () { 1181 transformed[this] = true; 1182 }); 1183 data = transformed; 1184 } 1185 return data; 1186 }, 1187 1188 // http://jqueryvalidation.org/jQuery.validator.addMethod/ 1189 addMethod: function (name, method, message) { 1190 $.validator.methods[name] = method; 1191 $.validator.messages[name] = message !== undefined ? message : $.validator.messages[name]; 1192 if (method.length < 3) { 1193 $.validator.addClassRules(name, $.validator.normalizeRule(name)); 1194 } 1195 }, 1196 1197 methods: { 1198 1199 // http://jqueryvalidation.org/required-method/ 1200 required: function (value, element, param) { 1201 // check if dependency is met 1202 if (!this.depend(param, element)) { 1203 return "dependency-mismatch"; 1204 } 1205 if (element.nodeName.toLowerCase() === "select") { 1206 // could be an array for select-multiple or a string, both are fine this way 1207 var val = $(element).val(); 1208 return val && val.length > 0; 1209 } 1210 if (this.checkable(element)) { 1211 return this.getLength(value, element) > 0; 1212 } 1213 return value.length > 0; 1214 }, 1215 1216 // http://jqueryvalidation.org/email-method/ 1217 email: function (value, element) { 1218 // From https://html.spec.whatwg.org/multipage/forms.html#valid-e-mail-address 1219 // Retrieved 2014-01-14 1220 // If you have a problem with this implementation, report a bug against the above spec 1221 // Or use custom methods to implement your own email validation 1222 return this.optional(element) || /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test(value); 1223 }, 1224 1225 // http://jqueryvalidation.org/url-method/ 1226 url: function (value, element) { 1227 1228 // Copyright (c) 2010-2013 Diego Perini, MIT licensed 1229 // https://gist.github.com/dperini/729294 1230 // see also https://mathiasbynens.be/demo/url-regex 1231 // modified to allow protocol-relative URLs
1232 return this.optional(element) || /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[/?#]\S*)?$/i.test(value); 1233 }, 1234 1235 // http://jqueryvalidation.org/date-method/ 1236 date: function (value, element) { 1237 return this.optional(element) || !/Invalid|NaN/.test(new Date(value).toString()); 1238 }, 1239 1240 // http://jqueryvalidation.org/dateISO-method/ 1241 dateISO: function (value, element) { 1242 return this.optional(element) || /^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test(value); 1243 }, 1244 1245 // http://jqueryvalidation.org/number-method/ 1246 number: function (value, element) { 1247 return this.optional(element) || /^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(value); 1248 }, 1249 1250 // http://jqueryvalidation.org/digits-method/ 1251 digits: function (value, element) { 1252 return this.optional(element) || /^\d+$/.test(value); 1253 }, 1254 1255 // http://jqueryvalidation.org/creditcard-method/ 1256 // based on http://en.wikipedia.org/wiki/Luhn_algorithm 1257 creditcard: function (value, element) { 1258 if (this.optional(element)) { 1259 return "dependency-mismatch"; 1260 } 1261 // accept only spaces, digits and dashes 1262 if (/[^0-9 \-]+/.test(value)) { 1263 return false; 1264 } 1265 var nCheck = 0, 1266 nDigit = 0, 1267 bEven = false, 1268 n, cDigit; 1269 1270 value = value.replace(/\D/g, ""); 1271 1272 // Basing min and max length on 1273 // http://developer.ean.com/general_info/Valid_Credit_Card_Types 1274 if (value.length < 13 || value.length > 19) { 1275 return false; 1276 } 1277 1278 for (n = value.length - 1; n >= 0; n--) { 1279 cDigit = value.charAt(n); 1280 nDigit = parseInt(cDigit, 10); 1281 if (bEven) { 1282 if ((nDigit *= 2) > 9) { 1283 nDigit -= 9; 1284 } 1285 } 1286 nCheck += nDigit; 1287 bEven = !bEven; 1288 } 1289 1290 return (nCheck % 10) === 0; 1291 }, 1292 1293 // http://jqueryvalidation.org/minlength-method/ 1294 minlength: function (value, element, param) { 1295 var length = $.isArray(value) ? value.length : this.getLength(value, element); 1296 return this.optional(element) || length >= param; 1297 }, 1298 1299 // http://jqueryvalidation.org/maxlength-method/ 1300 maxlength: function (value, element, param) { 1301 var length = $.isArray(value) ? value.length : this.getLength(value, element); 1302 return this.optional(element) || length <= param; 1303 }, 1304 1305 // http://jqueryvalidation.org/rangelength-method/ 1306 rangelength: function (value, element, param) { 1307 var length = $.isArray(value) ? value.length : this.getLength(value, element); 1308 return this.optional(element) || (length >= param[0] && length <= param[1]); 1309 }, 1310 1311 // http://jqueryvalidation.org/min-method/ 1312 min: function (value, element, param) { 1313 return this.optional(element) || value >= param; 1314 }, 1315 1316 // http://jqueryvalidation.org/max-method/ 1317 max: function (value, element, param) { 1318 return this.optional(element) || value <= param; 1319 }, 1320 1321 // http://jqueryvalidation.org/range-method/ 1322 range: function (value, element, param) { 1323 return this.optional(element) || (value >= param[0] && value <= param[1]); 1324 }, 1325 1326 // http://jqueryvalidation.org/equalTo-method/ 1327 equalTo: function (value, element, param) { 1328 // bind to the blur event of the target in order to revalidate whenever the target field is updated 1329 // TODO find a way to bind the event just once, avoiding the unbind-rebind overhead 1330 var target = $(param); 1331 if (this.settings.onfocusout) { 1332 target.off(".validate-equalTo").on("blur.validate-equalTo", function () { 1333 $(element).valid(); 1334 }); 1335 } 1336 return value === target.val(); 1337 }, 1338 1339 // http://jqueryvalidation.org/remote-method/ 1340 remote: function (value, element, param) { 1341 if (this.optional(element)) { 1342 return "dependency-mismatch"; 1343 } 1344 1345 var previous = this.previousValue(element), 1346 validator, data; 1347 1348 if (!this.settings.messages[element.name]) { 1349 this.settings.messages[element.name] = {}; 1350 } 1351 previous.originalMessage = this.settings.messages[element.name].remote; 1352 this.settings.messages[element.name].remote = previous.message; 1353 1354 param = typeof param === "string" && { 1355 url: param 1356 } || param; 1357 1358 if (previous.old === value) { 1359 return previous.valid; 1360 } 1361 1362 previous.old = value; 1363 validator = this;
1364 this.startRequest(element); 1365 data = {}; 1366 data[element.name] = value; 1367 $.ajax($.extend(true, { 1368 mode: "abort", 1369 port: "validate" + element.name, 1370 dataType: "json", 1371 data: data, 1372 context: validator.currentForm, 1373 success: function (response) { 1374 var valid = response === true || response === "true", 1375 errors, message, submitted; 1376 1377 validator.settings.messages[element.name].remote = previous.originalMessage; 1378 if (valid) { 1379 submitted = validator.formSubmitted; 1380 validator.prepareElement(element); 1381 validator.formSubmitted = submitted; 1382 validator.successList.push(element); 1383 delete validator.invalid[element.name]; 1384 validator.showErrors(); 1385 } else { 1386 errors = {}; 1387 message = response || validator.defaultMessage(element, "remote"); 1388 errors[element.name] = previous.message = $.isFunction(message) ? message(value) : message; 1389 validator.invalid[element.name] = true; 1390 validator.showErrors(errors); 1391 } 1392 previous.valid = valid; 1393 validator.stopRequest(element, valid); 1394 } 1395 }, param)); 1396 return "pending"; 1397 } 1398 } 1399 1400 }); 1401 1402 // ajax mode: abort 1403 // usage: $.ajax({ mode: "abort"[, port: "uniqueport"]}); 1404 // if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort() 1405 1406 var pendingRequests = {}, 1407 ajax; 1408 // Use a prefilter if available (1.5+) 1409 if ($.ajaxPrefilter) { 1410 $.ajaxPrefilter(function (settings, _, xhr) { 1411 var port = settings.port; 1412 if (settings.mode === "abort") { 1413 if (pendingRequests[port]) { 1414 pendingRequests[port].abort(); 1415 } 1416 pendingRequests[port] = xhr; 1417 } 1418 }); 1419 } else { 1420 // Proxy ajax 1421 ajax = $.ajax; 1422 $.ajax = function (settings) { 1423 var mode = ("mode" in settings ? settings : $.ajaxSettings).mode, 1424 port = ("port" in settings ? settings : $.ajaxSettings).port; 1425 if (mode === "abort") { 1426 if (pendingRequests[port]) { 1427 pendingRequests[port].abort(); 1428 } 1429 pendingRequests[port] = ajax.apply(this, arguments); 1430 return pendingRequests[port]; 1431 } 1432 return ajax.apply(this, arguments); 1433 }; 1434 } 1435 1436 /* 1437 * Translated default messages for the jQuery validation plugin. 1438 * Locale: DE (German, Deutsch) 1439 */ 1440 $.extend($.validator.messages, { 1441 required: "Dieses Feld ist ein Pflichtfeld.", 1442 maxlength: $.validator.format("Geben Sie bitte maximal {0} Zeichen ein."), 1443 minlength: $.validator.format("Geben Sie bitte mindestens {0} Zeichen ein."), 1444 rangelength: $.validator.format("Geben Sie bitte mindestens {0} und maximal {1} Zeichen ein."), 1445 email: "Geben Sie bitte eine gültige E-Mail Adresse ein.", 1446 url: "Geben Sie bitte eine gültige URL ein.", 1447 date: "Bitte geben Sie ein gültiges Datum ein.", 1448 number: "Geben Sie bitte eine Nummer ein.", 1449 digits: "Geben Sie bitte nur Ziffern ein.", 1450 equalTo: "Bitte denselben Wert wiederholen.", 1451 range: $.validator.format("Geben Sie bitte einen Wert zwischen {0} und {1} ein."), 1452 max: $.validator.format("Geben Sie bitte einen Wert kleiner oder gleich {0} ein."), 1453 min: $.validator.format("Geben Sie bitte einen Wert gröÃer oder gleich {0} ein."), 1454 creditcard: "Geben Sie bitte eine gültige Kreditkarten-Nummer ein." 1455 }); 1456 1457 /* Voila Captcha check */ 1458 $.extend($.validator.addMethod( 1459 "captcha", 1460 function (captcha, element) { 1461 var captValue = false; 1462 if (captcha !== "") { 1463 $.ajax({
1464 type: "GET", 1465 async: false, 1466 url: vConfig.db + "(web_formular_checkcaptcha)?OpenAgent", 1467 data: "captcha=" + captcha, 1468 success: function (msg) { 1469 if ($.trim(msg) == "ERROR") { 1470 captValue = false; 1471 } else { 1472 captValue = true; 1473 } 1474 } 1475 }); 1476 } 1477 return captValue; 1478 }, 1479 "Der Sicherheitscode wurde nicht korrekt eingegeben!" 1480 )); 1481 1482 1483 $.extend($.validator.addMethod( 1484 "allowedMedia", 1485 function (mediaPath, element, paramArray) { 1486 1487 var allowedFilesArray = paramArray[0]; 1488 1489 if (mediaPath != "") { 1490 console.log(allowedFilesArray); 1491 1492 var mediaPathSplit = mediaPath.split('.'); 1493 var allowedFilesArrayLower = allowedFilesArray.map(function (value) { 1494 return value.toLowerCase(); 1495 }); 1496 var fileExtension = mediaPathSplit[mediaPathSplit.length - 1].toLowerCase(); 1497 1498 var r = allowedFilesArrayLower.indexOf(fileExtension) != -1 ? true : false; 1499 console.log(r); 1500 return r; 1501 1502 } 1503 1504 return true; 1505 }, 1506 $.validator.format("Kein gültiges Dateiformat, nur {0} Dateien erlaubt") 1507 )); 1508 1509 1510}));
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.