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