1/* jqBootstrapValidation 2 * A plugin for automating validation on Twitter Bootstrap formatted forms. 3 * 4 * v1.3.6 5 * 6 * License: MIT <http://opensource.org/licenses/mit-license.php> - see LICENSE file 7 * 8 * http://ReactiveRaven.github.com/jqBootstrapValidation/ 9 */ 10 11(function( $ ){ 12 var lang = 'ja'; 13 if($('#lang').length > 0){ 14 lang = $('#lang').val(); 15 } 16 17 var createdElements = []; 18 19 var defaults = { 20 options: { 21 prependExistingHelpBlock: false, 22 sniffHtml: true, // sniff for 'required', 'maxlength', etc 23 preventSubmit: true, // stop the form submit event from firing if validation fails 24 submitError: false, // function called if there is an error when trying to submit 25 submitSuccess: false, // function called just before a successful submit event is sent to the server 26 semanticallyStrict: false, // set to true to tidy up generated HTML output 27 autoAdd: { 28 helpBlocks: true 29 }, 30 filter: function () { 31 // return $(this).is(":visible"); // only validate elements you can see 32 return true; // validate everything 33 } 34 }, 35 methods: { 36 init : function( options ) { 37 38 var settings = $.extend(true, {}, defaults); 39 40 settings.options = $.extend(true, settings.options, options); 41 42 var $siblingElements = this; 43 44 var uniqueForms = $.unique( 45 $siblingElements.map( function () { 46 return $(this).parents("form")[0]; 47 }).toArray() 48 ); 49 50 $(uniqueForms).bind("submit", function (e) { 51 var $form = $(this); 52 var warningsFound = 0; 53 var $inputs = $form.find("input,textarea,select").not("[type=submit],[type=image]").filter(settings.options.filter); 54 $inputs.trigger("submit.validation").trigger("validationLostFocus.validation"); 55 56 $inputs.each(function (i, el) { 57 var $this = $(el), 58 $controlGroup = $this.parents(".form-group").first(); 59 if ( 60 $controlGroup.hasClass("warning") 61 ) { 62 $controlGroup.removeClass("warning").addClass("error"); 63 warningsFound++; 64 } 65 }); 66 67 $inputs.trigger("validationLostFocus.validation"); 68 69 if (warningsFound) { 70 if (settings.options.preventSubmit) { 71 e.preventDefault(); 72 } 73 $form.addClass("error"); 74 if ($.isFunction(settings.options.submitError)) { 75 settings.options.submitError($form, e, $inputs.jqBootstrapValidation("collectErrors", true)); 76 } 77 } else { 78 $form.removeClass("error"); 79 if ($.isFunction(settings.options.submitSuccess)) { 80 settings.options.submitSuccess($form, e); 81 } 82 } 83 }); 84 85 return this.each(function(){ 86 87 // Get references to everything we're interested in 88 var $this = $(this), 89 $controlGroup = $this.parents(".form-group").first(), 90 $helpBlock = $controlGroup.find(".help-block").first(), 91 $form = $this.parents("form").first(), 92 validatorNames = []; 93 94 // create message container if not exists 95 if (!$helpBlock.length && settings.options.autoAdd && settings.options.autoAdd.helpBlocks) { 96 $helpBlock = $('<div class="help-block" />'); 97 $controlGroup.find('.controls').append($helpBlock); 98 createdElements.push($helpBlock[0]); 99 } 100 101 // ============================================================= 102 // SNIFF HTML FOR VALIDATORS 103 // ============================================================= 104 105 // *snort sniff snuffle* 106 107 if (settings.options.sniffHtml) { 108 var message = ""; 109 // --------------------------------------------------------- 110 // PATTERN 111 // --------------------------------------------------------- 112 if ($this.attr("pattern") !== undefined) { 113 message = "æå®ãããå½¢å¼ã§å ¥åãã¦ãã ãã<!-- data-validation-pattern-message to override -->"; 114 if ($this.data("validationPatternMessage")) { 115 message = $this.data("validationPatternMessage"); 116 } 117 $this.data("validationPatternMessage", message); 118 $this.data("validationPatternRegex", $this.attr("pattern")); 119 } 120 // --------------------------------------------------------- 121 // MAX 122 // --------------------------------------------------------- 123 if ($this.attr("max") !== undefined || $this.attr("aria-valuemax") !== undefined) { 124 var max = ($this.attr("max") !== undefined ? $this.attr("max") : $this.attr("aria-valuemax")); 125 message = "Too high: Maximum of '" + max + "'<!-- data-validation-max-message to override -->"; 126 if ($this.data("validationMaxMessage")) { 127 message = $this.data("validationMaxMessage"); 128 } 129 $this.data("validationMaxMessage", message); 130 $this.data("validationMaxMax", max); 131 } 132 // --------------------------------------------------------- 133 // MIN 134 // --------------------------------------------------------- 135 if ($this.attr("min") !== undefined || $this.attr("aria-valuemin") !== undefined) { 136 var min = ($this.attr("min") !== undefined ? $this.attr("min") : $this.attr("aria-valuemin")); 137 message = "Too low: Minimum of '" + min + "'<!-- data-validation-min-message to override -->"; 138 if ($this.data("validationMinMessage")) { 139 message = $this.data("validationMinMessage"); 140 } 141 $this.data("validationMinMessage", message); 142 $this.data("validationMinMin", min); 143 } 144 // --------------------------------------------------------- 145 // MAXLENGTH 146 // --------------------------------------------------------- 147 if ($this.attr("maxlength") !== undefined) { 148 message = "Too long: Maximum of '" + $this.attr("maxlength") + "' characters<!-- data-validation-maxlength-message to override -->"; 149 if ($this.data("validationMaxlengthMessage")) { 150 message = $this.data("validationMaxlengthMessage"); 151 } 152 $this.data("validationMaxlengthMessage", message); 153 $this.data("validationMaxlengthMaxlength", $this.attr("maxlength")); 154 } 155 // --------------------------------------------------------- 156 // MINLENGTH 157 // --------------------------------------------------------- 158 if ($this.attr("minlength") !== undefined) { 159 message = "Too short: Minimum of '" + $this.attr("minlength") + "' characters<!-- data-validation-minlength-message to override -->"; 160 if ($this.data("validationMinlengthMessage")) { 161 message = $this.data("validationMinlengthMessage"); 162 } 163 $this.data("validationMinlengthMessage", message); 164 $this.data("validationMinlengthMinlength", $this.attr("minlength")); 165 } 166 // --------------------------------------------------------- 167 // REQUIRED 168 // --------------------------------------------------------- 169 if ($this.attr("required") !== undefined || $this.attr("aria-required") !== undefined) { 170 message = settings.builtInValidators.required.message; 171 if ($this.data("validationRequiredMessage")) { 172 message = $this.data("validationRequiredMessage"); 173 } 174 $this.data("validationRequiredMessage", message); 175 } 176 // --------------------------------------------------------- 177 // NUMBER 178 // --------------------------------------------------------- 179 if ($this.attr("type") !== undefined && $this.attr("type").toLowerCase() === "number") { 180 message = settings.builtInValidators.number.message; 181 if ($this.data("validationNumberMessage")) { 182 message = $this.data("validationNumberMessage"); 183 } 184 $this.data("validationNumberMessage", message); 185 } 186 // --------------------------------------------------------- 187 // EMAIL 188 // --------------------------------------------------------- 189 if ($this.attr("type") !== undefined && $this.attr("type").toLowerCase() === "email") { 190 message = (lang == "ja"? "ã¡ã¼ã«ã¢ãã¬ã¹ããå ¥åãã ãã<!-- data-validator-validemail-message to override -->" : "Not a valid email address<!-- data-validator-validemail-message to override -->"); 191 if ($this.data("validationValidemailMessage")) { 192 message = $this.data("validationValidemailMessage"); 193 } else if ($this.data("validationEmailMessage")) { 194 message = $this.data("validationEmailMessage"); 195 } 196 $this.data("validationValidemailMessage", message); 197 } 198 // --------------------------------------------------------- 199 // MINCHECKED 200 // --------------------------------------------------------- 201 if ($this.attr("minchecked") !== undefined) { 202 message = "Not enough options checked; Minimum of '" + $this.attr("minchecked") + "' required<!-- data-validation-minchecked-message to override -->"; 203 if ($this.data("validationMincheckedMessage")) { 204 message = $this.data("validationMincheckedMessage"); 205 } 206 $this.data("validationMincheckedMessage", message); 207 $this.data("validationMincheckedMinchecked", $this.attr("minchecked")); 208 } 209 // --------------------------------------------------------- 210 // MAXCHECKED 211 // --------------------------------------------------------- 212 if ($this.attr("maxchecked") !== undefined) { 213 message = "Too many options checked; Maximum of '" + $this.attr("maxchecked") + "' required<!-- data-validation-maxchecked-message to override -->";
214 if ($this.data("validationMaxcheckedMessage")) { 215 message = $this.data("validationMaxcheckedMessage"); 216 } 217 $this.data("validationMaxcheckedMessage", message); 218 $this.data("validationMaxcheckedMaxchecked", $this.attr("maxchecked")); 219 } 220 } 221 222 // ============================================================= 223 // COLLECT VALIDATOR NAMES 224 // ============================================================= 225 226 // Get named validators 227 if ($this.data("validation") !== undefined) { 228 validatorNames = $this.data("validation").split(","); 229 } 230 231 // Get extra ones defined on the element's data attributes 232 $.each($this.data(), function (i, el) { 233 var parts = i.replace(/([A-Z])/g, ",$1").split(","); 234 if (parts[0] === "validation" && parts[1]) { 235 validatorNames.push(parts[1]); 236 } 237 }); 238 239 // ============================================================= 240 // NORMALISE VALIDATOR NAMES 241 // ============================================================= 242 243 var validatorNamesToInspect = validatorNames; 244 var newValidatorNamesToInspect = []; 245 246 do // repeatedly expand 'shortcut' validators into their real validators 247 { 248 // Uppercase only the first letter of each name 249 $.each(validatorNames, function (i, el) { 250 validatorNames[i] = formatValidatorName(el); 251 }); 252 253 // Remove duplicate validator names 254 validatorNames = $.unique(validatorNames); 255 256 // Pull out the new validator names from each shortcut 257 newValidatorNamesToInspect = []; 258 $.each(validatorNamesToInspect, function(i, el) { 259 if ($this.data("validation" + el + "Shortcut") !== undefined) { 260 // Are these custom validators? 261 // Pull them out! 262 $.each($this.data("validation" + el + "Shortcut").split(","), function(i2, el2) { 263 newValidatorNamesToInspect.push(el2); 264 }); 265 } else if (settings.builtInValidators[el.toLowerCase()]) { 266 // Is this a recognised built-in? 267 // Pull it out! 268 var validator = settings.builtInValidators[el.toLowerCase()]; 269 if (validator.type.toLowerCase() === "shortcut") { 270 $.each(validator.shortcut.split(","), function (i, el) { 271 el = formatValidatorName(el); 272 newValidatorNamesToInspect.push(el); 273 validatorNames.push(el); 274 }); 275 } 276 } 277 }); 278 279 validatorNamesToInspect = newValidatorNamesToInspect; 280 281 } while (validatorNamesToInspect.length > 0) 282 283 // ============================================================= 284 // SET UP VALIDATOR ARRAYS 285 // ============================================================= 286 287 var validators = {}; 288 289 $.each(validatorNames, function (i, el) { 290 // Set up the 'override' message 291 var message = $this.data("validation" + el + "Message"); 292 var hasOverrideMessage = (message !== undefined); 293 var foundValidator = false; 294 message = 295 ( 296 message 297 ? message 298 : "'" + el + "' validation failed <!-- Add attribute 'data-validation-" + el.toLowerCase() + "-message' to input to change this message -->" 299 ) 300 ; 301 302 $.each( 303 settings.validatorTypes, 304 function (validatorType, validatorTemplate) { 305 if (validators[validatorType] === undefined) { 306 validators[validatorType] = []; 307 } 308 if (!foundValidator && $this.data("validation" + el + formatValidatorName(validatorTemplate.name)) !== undefined) { 309 validators[validatorType].push( 310 $.extend( 311 true, 312 { 313 name: formatValidatorName(validatorTemplate.name), 314 message: message 315 }, 316 validatorTemplate.init($this, el) 317 ) 318 ); 319 foundValidator = true; 320 } 321 } 322 ); 323 324 if (!foundValidator && settings.builtInValidators[el.toLowerCase()]) { 325
326 var validator = $.extend(true, {}, settings.builtInValidators[el.toLowerCase()]); 327 if (hasOverrideMessage) { 328 validator.message = message; 329 } 330 var validatorType = validator.type.toLowerCase(); 331 332 if (validatorType === "shortcut") { 333 foundValidator = true; 334 } else { 335 $.each( 336 settings.validatorTypes, 337 function (validatorTemplateType, validatorTemplate) { 338 if (validators[validatorTemplateType] === undefined) { 339 validators[validatorTemplateType] = []; 340 } 341 if (!foundValidator && validatorType === validatorTemplateType.toLowerCase()) { 342 $this.data("validation" + el + formatValidatorName(validatorTemplate.name), validator[validatorTemplate.name.toLowerCase()]); 343 validators[validatorType].push( 344 $.extend( 345 validator, 346 validatorTemplate.init($this, el) 347 ) 348 ); 349 foundValidator = true; 350 } 351 } 352 ); 353 } 354 } 355 356 if (! foundValidator) { 357 $.error("Cannot find validation info for '" + el + "'"); 358 } 359 }); 360 361 // ============================================================= 362 // STORE FALLBACK VALUES 363 // ============================================================= 364 365 $helpBlock.data( 366 "original-contents", 367 ( 368 $helpBlock.data("original-contents") 369 ? $helpBlock.data("original-contents") 370 : $helpBlock.html() 371 ) 372 ); 373 374 $helpBlock.data( 375 "original-role", 376 ( 377 $helpBlock.data("original-role") 378 ? $helpBlock.data("original-role") 379 : $helpBlock.attr("role") 380 ) 381 ); 382 383 $controlGroup.data( 384 "original-classes", 385 ( 386 $controlGroup.data("original-clases") 387 ? $controlGroup.data("original-classes") 388 : $controlGroup.attr("class") 389 ) 390 ); 391 392 $this.data( 393 "original-aria-invalid", 394 ( 395 $this.data("original-aria-invalid") 396 ? $this.data("original-aria-invalid") 397 : $this.attr("aria-invalid") 398 ) 399 ); 400 401 // ============================================================= 402 // VALIDATION 403 // ============================================================= 404 405 $this.bind( 406 "validation.validation", 407 function (event, params) { 408 409 var value = getValue($this); 410 411 // Get a list of the errors to apply 412 var errorsFound = []; 413 414 $.each(validators, function (validatorType, validatorTypeArray) { 415 if (value || value.length || (params && params.includeEmpty) || (!!settings.validatorTypes[validatorType].blockSubmit && params && !!params.submitting)) { 416 $.each(validatorTypeArray, function (i, validator) { 417 if (settings.validatorTypes[validatorType].validate($this, value, validator)) { 418 errorsFound.push(validator.message); 419 } 420 }); 421 } 422 }); 423 424 return errorsFound; 425 } 426 ); 427 428 $this.bind( 429 "getValidators.validation", 430 function () { 431 return validators; 432 } 433 ); 434 435 // ============================================================= 436 // WATCH FOR CHANGES 437 // ============================================================= 438 $this.bind( 439 "submit.validation", 440 function () { 441 return $this.triggerHandler("change.validation", {submitting: true}); 442 } 443 ); 444 $this.bind( 445 [ 446 "keyup", 447 "focus", 448 "blur", 449 "click", 450 "keydown", 451 "keypress", 452 "change" 453 ].join(".validation ") + ".validation", 454 function (e, params) { 455 456 var value = getValue($this); 457 458 var errorsFound = []; 459 460 $controlGroup.find("input,textarea,select").each(function (i, el) { 461 var oldCount = errorsFound.length; 462 $.each($(el).triggerHandler("validation.validation", params), function (j, message) { 463 errorsFound.push(message); 464 }); 465 if (errorsFound.length > oldCount) { 466 $(el).attr("aria-invalid", "true"); 467 } else { 468 var original = $this.data("original-aria-invalid"); 469 $(el).attr("aria-invalid", (original !== undefined ? original : false)); 470 } 471 }); 472 473 $form.find("input,select,textarea").not($this).not("[name=\"" + $this.attr("name") + "\"]").trigger("validationLostFocus.validation"); 474 475 errorsFound = $.unique(errorsFound.sort()); 476 477 // Were there any errors? 478 if (errorsFound.length) { 479 // Better flag it up as a warning. 480 $controlGroup.removeClass("success error").addClass("warning"); 481 482 // How many errors did we find? 483 if (settings.options.semanticallyStrict && errorsFound.length === 1) { 484 // Only one? Being strict? Just output it. 485 $helpBlock.html(errorsFound[0] + 486 ( settings.options.prependExistingHelpBlock ? $helpBlock.data("original-contents") : "" )); 487 } else { 488 // Multiple? Being sloppy? Glue them together into an UL. 489 $helpBlock.html("<ul role=\"alert\"><li>" + errorsFound.join("</li><li>") + "</li></ul>" + 490 ( settings.options.prependExistingHelpBlock ? $helpBlock.data("original-contents") : "" )); 491 } 492 } else { 493 $controlGroup.removeClass("warning error success"); 494 if (value.length > 0) { 495 $controlGroup.addClass("success"); 496 } 497 $helpBlock.html($helpBlock.data("original-contents")); 498 } 499 500 if (e.type === "blur") { 501 $controlGroup.removeClass("success"); 502 } 503 } 504 ); 505 $this.bind("validationLostFocus.validation", function () { 506 $controlGroup.removeClass("success"); 507 }); 508 }); 509 }, 510 destroy : function( ) { 511 512 return this.each( 513 function() { 514 515 var 516 $this = $(this), 517 $controlGroup = $this.parents(".form-group").first(), 518 $helpBlock = $controlGroup.find(".help-block").first(); 519 520 // remove our events 521 $this.unbind('.validation'); // events are namespaced. 522 // reset help text 523 $helpBlock.html($helpBlock.data("original-contents")); 524 // reset classes 525 $controlGroup.attr("class", $controlGroup.data("original-classes")); 526 // reset aria 527 $this.attr("aria-invalid", $this.data("original-aria-invalid")); 528 // reset role 529 $helpBlock.attr("role", $this.data("original-role")); 530 // remove all elements we created 531 if (createdElements.indexOf($helpBlock[0]) > -1) { 532 $helpBlock.remove(); 533 } 534 535 } 536 ); 537 538 }, 539 collectErrors : function(includeEmpty) { 540 541 var errorMessages = {}; 542 this.each(function (i, el) { 543 var $el = $(el); 544 var name = $el.attr("name"); 545 var errors = $el.triggerHandler("validation.validation", {includeEmpty: true}); 546 errorMessages[name] = $.extend(true, errors, errorMessages[name]); 547 }); 548 549 $.each(errorMessages, function (i, el) { 550 if (el.length === 0) { 551 delete errorMessages[i]; 552 } 553 }); 554 555 return errorMessages; 556 557 }, 558 hasErrors: function() { 559 560 var errorMessages = []; 561 562 this.each(function (i, el) { 563 errorMessages = errorMessages.concat( 564 $(el).triggerHandler("getValidators.validation") ? $(el).triggerHandler("validation.validation", {submitting: true}) : [] 565 ); 566 }); 567 568 return (errorMessages.length > 0); 569 }, 570 override : function (newDefaults) { 571 defaults = $.extend(true, defaults, newDefaults); 572 } 573 }, 574 validatorTypes: { 575 callback: { 576 name: "callback", 577 init: function ($this, name) { 578 return { 579 validatorName: name, 580 callback: $this.data("validation" + name + "Callback"),
581 lastValue: $this.val(), 582 lastValid: true, 583 lastFinished: true 584 }; 585 }, 586 validate: function ($this, value, validator) { 587 if (validator.lastValue === value && validator.lastFinished) { 588 return !validator.lastValid; 589 } 590 591 if (validator.lastFinished === true) 592 { 593 validator.lastValue = value; 594 validator.lastValid = true; 595 validator.lastFinished = false; 596 597 var rrjqbvValidator = validator; 598 var rrjqbvThis = $this; 599 executeFunctionByName( 600 validator.callback, 601 window, 602 $this, 603 value, 604 function (data) { 605 if (rrjqbvValidator.lastValue === data.value) { 606 rrjqbvValidator.lastValid = data.valid; 607 if (data.message) { 608 rrjqbvValidator.message = data.message; 609 } 610 rrjqbvValidator.lastFinished = true; 611 rrjqbvThis.data("validation" + rrjqbvValidator.validatorName + "Message", rrjqbvValidator.message); 612 // Timeout is set to avoid problems with the events being considered 'already fired' 613 setTimeout(function () { 614 rrjqbvThis.trigger("change.validation"); 615 }, 1); // doesn't need a long timeout, just long enough for the event bubble to burst 616 } 617 } 618 ); 619 } 620 621 return false; 622 623 } 624 }, 625 ajax: { 626 name: "ajax", 627 init: function ($this, name) { 628 return { 629 validatorName: name, 630 url: $this.data("validation" + name + "Ajax"), 631 lastValue: $this.val(), 632 lastValid: true, 633 lastFinished: true 634 }; 635 }, 636 validate: function ($this, value, validator) { 637 if (""+validator.lastValue === ""+value && validator.lastFinished === true) { 638 return validator.lastValid === false; 639 } 640 641 if (validator.lastFinished === true) 642 { 643 validator.lastValue = value; 644 validator.lastValid = true; 645 validator.lastFinished = false; 646 $.ajax({ 647 url: validator.url, 648 data: "value=" + value + "&field=" + $this.attr("name"), 649 dataType: "json", 650 success: function (data) { 651 if (""+validator.lastValue === ""+data.value) { 652 validator.lastValid = !!(data.valid); 653 if (data.message) { 654 validator.message = data.message; 655 } 656 validator.lastFinished = true; 657 $this.data("validation" + validator.validatorName + "Message", validator.message); 658 // Timeout is set to avoid problems with the events being considered 'already fired' 659 setTimeout(function () { 660 $this.trigger("change.validation"); 661 }, 1); // doesn't need a long timeout, just long enough for the event bubble to burst 662 } 663 }, 664 failure: function () { 665 validator.lastValid = true; 666 validator.message = "ajax call failed"; 667 validator.lastFinished = true; 668 $this.data("validation" + validator.validatorName + "Message", validator.message); 669 // Timeout is set to avoid problems with the events being considered 'already fired' 670 setTimeout(function () { 671 $this.trigger("change.validation"); 672 }, 1); // doesn't need a long timeout, just long enough for the event bubble to burst 673 } 674 }); 675 } 676 677 return false; 678 679 } 680 }, 681 regex: { 682 name: "regex", 683 init: function ($this, name) { 684 return {regex: regexFromString($this.data("validation" + name + "Regex"))}; 685 }, 686 validate: function ($this, value, validator) { 687 return (!validator.regex.test(value) && ! validator.negative) 688 || (validator.regex.test(value) && validator.negative); 689 } 690 }, 691 required: { 692 name: "required", 693 init: function ($this, name) { 694 return {}; 695 }, 696 validate: function ($this, value, validator) { 697 return !!(value.length === 0 && ! validator.negative) 698 || !!(value.length > 0 && validator.negative); 699 }, 700 blockSubmit: true 701 }, 702 match: { 703 name: "match", 704 init: function ($this, name) { 705 var element = $this.parents("form").first().find("[name=\"" + $this.data("validation" + name + "Match") + "\"]").first(); 706 element.bind("validation.validation", function () { 707 $this.trigger("change.validation", {submitting: true}); 708 }); 709 return {"element": element}; 710 }, 711 validate: function ($this, value, validator) { 712 return (value !== validator.element.val() && ! validator.negative) 713 || (value === validator.element.val() && validator.negative); 714 }, 715 blockSubmit: true 716 }, 717 max: { 718 name: "max", 719 init: function ($this, name) { 720 return {max: $this.data("validation" + name + "Max")}; 721 }, 722 validate: function ($this, value, validator) { 723 return (parseFloat(value, 10) > parseFloat(validator.max, 10) && ! validator.negative) 724 || (parseFloat(value, 10) <= parseFloat(validator.max, 10) && validator.negative); 725 } 726 }, 727 min: { 728 name: "min", 729 init: function ($this, name) { 730 return {min: $this.data("validation" + name + "Min")}; 731 }, 732 validate: function ($this, value, validator) { 733 return (parseFloat(value) < parseFloat(validator.min) && ! validator.negative) 734 || (parseFloat(value) >= parseFloat(validator.min) && validator.negative); 735 } 736 }, 737 maxlength: { 738 name: "maxlength", 739 init: function ($this, name) { 740 return {maxlength: $this.data("validation" + name + "Maxlength")}; 741 }, 742 validate: function ($this, value, validator) { 743 return ((value.length > validator.maxlength) && ! validator.negative) 744 || ((value.length <= validator.maxlength) && validator.negative); 745 } 746 }, 747 minlength: { 748 name: "minlength", 749 init: function ($this, name) { 750 return {minlength: $this.data("validation" + name + "Minlength")}; 751 }, 752 validate: function ($this, value, validator) { 753 return ((value.length < validator.minlength) && ! validator.negative) 754 || ((value.length >= validator.minlength) && validator.negative); 755 } 756 }, 757 maxchecked: { 758 name: "maxchecked", 759 init: function ($this, name) { 760 var elements = $this.parents("form").first().find("[name=\"" + $this.attr("name") + "\"]"); 761 elements.bind("click.validation", function () { 762 $this.trigger("change.validation", {includeEmpty: true}); 763 }); 764 return {maxchecked: $this.data("validation" + name + "Maxchecked"), elements: elements}; 765 }, 766 validate: function ($this, value, validator) { 767 return (validator.elements.filter(":checked").length > validator.maxchecked && ! validator.negative) 768 || (validator.elements.filter(":checked").length <= validator.maxchecked && validator.negative); 769 }, 770 blockSubmit: true 771 }, 772 minchecked: { 773 name: "minchecked", 774 init: function ($this, name) { 775 var elements = $this.parents("form").first().find("[name=\"" + $this.attr("name") + "\"]"); 776 elements.bind("click.validation", function () { 777 $this.trigger("change.validation", {includeEmpty: true}); 778 }); 779 return {minchecked: $this.data("validation" + name + "Minchecked"), elements: elements}; 780 }, 781 validate: function ($this, value, validator) { 782 return (validator.elements.filter(":checked").length < validator.minchecked && ! validator.negative) 783 || (validator.elements.filter(":checked").length >= validator.minchecked && validator.negative); 784 }, 785 blockSubmit: true 786 } 787 }, 788 builtInValidators: { 789 email: { 790 name: "Email", 791 type: "shortcut", 792 shortcut: "validemail" 793 }, 794 validemail: { 795 name: "Validemail", 796 type: "regex", 797 regex: "[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\\.[A-Za-z]{2,4}", 798 message: lang == "ja"? "ã¡ã¼ã«ã¢ãã¬ã¹ããå ¥åãã ãã<!-- data-validator-validemail-message to override -->" : "Not a valid email address<!-- data-validator-validemail-message to override -->" 799 }, 800 passwordagain: { 801 name: "Passwordagain", 802 type: "match", 803 match: "password", 804 message: "Does not match the given password<!-- data-validator-paswordagain-message to override -->" 805 }, 806 positive: { 807 name: "Positive", 808 type: "shortcut", 809 shortcut: "number,positivenumber" 810 }, 811 negative: { 812 name: "Negative", 813 type: "shortcut", 814 shortcut: "number,negativenumber" 815 }, 816 number: { 817 name: "Number", 818 type: "regex", 819 regex: "([+-]?\\\d+(\\\.\\\d*)?([eE][+-]?[0-9]+)?)?", 820 message: "Must be a number<!-- data-validator-number-message to override -->" 821 }, 822 integer: { 823 name: "Integer", 824 type: "regex", 825 regex: "[+-]?\\\d+", 826 message: "No decimal places allowed<!-- data-validator-integer-message to override -->" 827 }, 828 positivenumber: { 829 name: "Positivenumber", 830 type: "min", 831 min: 0, 832 message: "Must be a positive number<!-- data-validator-positivenumber-message to override -->" 833 }, 834 negativenumber: { 835 name: "Negativenumber", 836 type: "max", 837 max: 0, 838 message: "Must be a negative number<!-- data-validator-negativenumber-message to override -->" 839 }, 840 required: { 841 name: "Required", 842 type: "required", 843 message: "This is required<!-- data-validator-required-message to override -->" 844 }, 845 checkone: { 846 name: "Checkone", 847 type: "minchecked", 848 minchecked: 1, 849 message: "Check at least one option<!-- data-validation-checkone-message to override -->" 850 } 851 } 852 }; 853 854 var formatValidatorName = function (name) { 855 return name 856 .toLowerCase() 857 .replace( 858 /(^|\s)([a-z])/g , 859 function(m,p1,p2) { 860 return p1+p2.toUpperCase(); 861 } 862 ) 863 ; 864 }; 865 866 var getValue = function ($this) { 867 // Extract the value we're talking about 868 var value = $this.val(); 869 var type = $this.attr("type"); 870 if (type === "checkbox") { 871 value = ($this.is(":checked") ? value : ""); 872 } 873 if (type === "radio") { 874 value = ($('input[name="' + $this.attr("name") + '"]:checked').length > 0 ? value : ""); 875 } 876 return value; 877 }; 878 879 function regexFromString(inputstring) {
880 return new RegExp("^" + inputstring + "$"); 881 } 882 883 /** 884 * Thanks to Jason Bunting via StackOverflow.com 885 * 886 * http://stackoverflow.com/questions/359788/how-to-execute-a-javascript-function-when-i-have-its-name-as-a-string#answer-359910 887 * Short link: http://tinyurl.com/executeFunctionByName 888 **/ 889 function executeFunctionByName(functionName, context /*, args*/) { 890 var args = Array.prototype.slice.call(arguments).splice(2); 891 var namespaces = functionName.split("."); 892 var func = namespaces.pop(); 893 for(var i = 0; i < namespaces.length; i++) { 894 context = context[namespaces[i]]; 895 } 896 return context[func].apply(this, args); 897 } 898 899 $.fn.jqBootstrapValidation = function( method ) { 900 901 if ( defaults.methods[method] ) { 902 return defaults.methods[method].apply( this, Array.prototype.slice.call( arguments, 1 )); 903 } else if ( typeof method === 'object' || ! method ) { 904 return defaults.methods.init.apply( this, arguments ); 905 } else { 906 $.error( 'Method ' + method + ' does not exist on jQuery.jqBootstrapValidation' ); 907 return null; 908 } 909 910 }; 911 912 $.jqBootstrapValidation = function (options) { 913 $(":input").not("[type=image],[type=submit]").jqBootstrapValidation.apply(this,arguments); 914 }; 915 916})( 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.