|
31 | 31 |
|
32 | 32 | // Check if a validator for this form was already created
|
33 | 33 | var validator = $.data( this[ 0 ], "validator" );
|
| 34 | + |
34 | 35 | if ( validator ) {
|
35 | 36 | return validator;
|
36 | 37 | }
|
|
235 | 236 | // https://jqueryvalidation.org/filled-selector/
|
236 | 237 | filled: function( a ) {
|
237 | 238 | var val = $( a ).val();
|
| 239 | + |
238 | 240 | return val !== null && !!trim( "" + val );
|
239 | 241 | },
|
240 | 242 |
|
|
256 | 258 | if ( arguments.length === 1 ) {
|
257 | 259 | return function() {
|
258 | 260 | var args = $.makeArray( arguments );
|
| 261 | + |
259 | 262 | args.unshift( source );
|
260 | 263 | return $.validator.format.apply( this, args );
|
261 | 264 | };
|
|
404 | 407 | this.reset();
|
405 | 408 |
|
406 | 409 | var currentForm = this.currentForm,
|
407 |
| - groups = ( this.groups = {} ), |
| 410 | + groups = this.groups = {}, |
408 | 411 | rules;
|
| 412 | + |
409 | 413 | $.each( this.settings.groups, function( key, value ) {
|
410 | 414 | if ( typeof value === "string" ) {
|
411 | 415 | value = value.split( /\s/ );
|
|
420 | 424 | } );
|
421 | 425 |
|
422 | 426 | function delegate( event ) {
|
423 |
| - var isContentEditable = typeof $( this ).attr( "contenteditable" ) !== "undefined" && $( this ).attr( "contenteditable" ) !== "false"; |
| 427 | + var isContentEditable = typeof $( this ).attr( "contenteditable" ) !== "undefined" |
| 428 | + && $( this ).attr( "contenteditable" ) !== "false"; |
424 | 429 |
|
425 | 430 | // Set form expando on contenteditable
|
426 | 431 | if ( !this.form && isContentEditable ) {
|
|
437 | 442 | var validator = $.data( this.form, "validator" ),
|
438 | 443 | eventType = "on" + event.type.replace( /^validate/, "" ),
|
439 | 444 | settings = validator.settings;
|
| 445 | + |
440 | 446 | if ( settings[ eventType ] && !$( this ).is( settings.ignore ) ) {
|
441 | 447 | settings[ eventType ].call( validator, this, event );
|
442 | 448 | }
|
443 | 449 | }
|
444 | 450 |
|
445 | 451 | $( this.currentForm )
|
446 | 452 | .on( "focusin.validate focusout.validate keyup.validate",
|
447 |
| - ":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'], " + |
448 |
| - "[type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], " + |
449 |
| - "[type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'], " + |
| 453 | + ":text, [type='password'], [type='file'], " + |
| 454 | + "select, textarea, [type='number'], [type='search'], " + |
| 455 | + "[type='tel'], [type='url'], [type='email'], " + |
| 456 | + "[type='datetime'], [type='date'], [type='month'], " + |
| 457 | + "[type='week'], [type='time'], [type='datetime-local'], " + |
| 458 | + "[type='range'], [type='color'], " + |
450 | 459 | "[type='radio'], [type='checkbox'], [contenteditable], [type='button']", delegate )
|
451 | 460 |
|
452 | 461 | // Support: Chrome, oldIE
|
|
471 | 480 | },
|
472 | 481 |
|
473 | 482 | checkForm: function() {
|
| 483 | + if ($(this.currentForm).find('.bundle').length > 0 |
| 484 | + && $(this.currentForm).find('input[type="checkbox"]').length > 0) { |
| 485 | + return this.checkBundleForm(); |
| 486 | + } |
| 487 | + return this.checkDefaultForm(); |
| 488 | + }, |
| 489 | + |
| 490 | + checkBundleForm: function() { |
| 491 | + var optionNumber, elements, optionMap, el, option; |
| 492 | + |
| 493 | + this.prepareForm(); |
| 494 | + elements = this.elements(); |
| 495 | + optionMap = {}; |
| 496 | + for (var i = 0; i < elements.length; i++) { |
| 497 | + el = elements[i]; |
| 498 | + optionNumber = el.id.split('-')[2]; |
| 499 | + if (!optionMap[optionNumber]) { |
| 500 | + optionMap[optionNumber] = []; |
| 501 | + } |
| 502 | + optionMap[optionNumber].push(el); |
| 503 | + } |
| 504 | + for (option in optionMap) { |
| 505 | + if (optionMap.hasOwnProperty(option)) { |
| 506 | + this.processOptionGroup(optionMap[option]); |
| 507 | + } |
| 508 | + } |
| 509 | + return this.valid(); |
| 510 | + }, |
| 511 | + |
| 512 | + processOptionGroup: function(group) { |
| 513 | + if (group.length > 0) { |
| 514 | + this.check(group[0]); |
| 515 | + } |
| 516 | + }, |
| 517 | + |
| 518 | + checkDefaultForm: function() { |
474 | 519 | this.prepareForm();
|
475 |
| - for ( var i = 0, elements = ( this.currentElements = this.elements() ); elements[ i ]; i++ ) { |
476 |
| - this.check( elements[ i ] ); |
| 520 | + for (var i = 0, elements = (this.currentElements = this.elements()); elements[i]; i++) { |
| 521 | + this.check(elements[i]); |
477 | 522 | }
|
478 | 523 | return this.valid();
|
479 | 524 | },
|
|
595 | 640 | /* jshint unused: false */
|
596 | 641 | var count = 0,
|
597 | 642 | i;
|
| 643 | + |
598 | 644 | for ( i in obj ) {
|
599 | 645 |
|
600 | 646 | // This check allows counting elements with empty error
|
|
641 | 687 |
|
642 | 688 | findLastActive: function() {
|
643 | 689 | var lastActive = this.lastActive;
|
| 690 | + |
644 | 691 | return lastActive && $.grep( this.errorList, function( n ) {
|
645 | 692 | return n.element.name === lastActive.name;
|
646 | 693 | } ).length === 1 && lastActive;
|
|
657 | 704 | .not( this.settings.ignore )
|
658 | 705 | .filter( function() {
|
659 | 706 | var name = this.name || $( this ).attr( "name" ); // For contenteditable
|
660 |
| - var isContentEditable = typeof $( this ).attr( "contenteditable" ) !== "undefined" && $( this ).attr( "contenteditable" ) !== "false"; |
| 707 | + |
| 708 | + var isContentEditable = typeof $( this ).attr( "contenteditable" ) !== "undefined" |
| 709 | + && $( this ).attr( "contenteditable" ) !== "false"; |
661 | 710 |
|
662 | 711 | if ( !name && validator.settings.debug && window.console ) {
|
663 | 712 | console.error( "%o has no name assigned", this );
|
|
690 | 739 |
|
691 | 740 | errors: function() {
|
692 | 741 | var errorClass = this.settings.errorClass.split( " " ).join( "." );
|
| 742 | + |
693 | 743 | return $( this.settings.errorElement + "." + errorClass, this.errorContext );
|
694 | 744 | },
|
695 | 745 |
|
|
846 | 896 | // Return the custom message for the given element name and validation method
|
847 | 897 | customMessage: function( name, method ) {
|
848 | 898 | var m = this.settings.messages[ name ];
|
| 899 | + |
849 | 900 | return m && ( m.constructor === String ? m : m[ method ] );
|
850 | 901 | },
|
851 | 902 |
|
|
914 | 965 |
|
915 | 966 | defaultShowErrors: function() {
|
916 | 967 | var i, elements, error;
|
| 968 | + |
917 | 969 | for ( i = 0; this.errorList[ i ]; i++ ) {
|
918 | 970 | error = this.errorList[ i ];
|
919 | 971 | if ( this.settings.highlight ) {
|
|
1111 | 1163 |
|
1112 | 1164 | optional: function( element ) {
|
1113 | 1165 | var val = this.elementValue( element );
|
| 1166 | + |
1114 | 1167 | return !$.validator.methods.required.call( this, val, element ) && "dependency-mismatch";
|
1115 | 1168 | },
|
1116 | 1169 |
|
|
1282 | 1335 | }
|
1283 | 1336 |
|
1284 | 1337 | var meta = $.data(element.form, 'validator').settings.meta;
|
| 1338 | + |
1285 | 1339 | return meta ?
|
1286 | 1340 | $(element).metadata()[meta] :
|
1287 | 1341 | $(element).metadata();
|
1288 | 1342 | },
|
1289 |
| - |
1290 | 1343 | dataRules: function( element ) {
|
1291 | 1344 | var rules = {},
|
1292 | 1345 | $element = $( element ),
|
|
1328 | 1381 | }
|
1329 | 1382 | if ( val.param || val.depends ) {
|
1330 | 1383 | var keepRule = true;
|
| 1384 | + |
1331 | 1385 | switch ( typeof val.depends ) {
|
1332 | 1386 | case "string":
|
1333 | 1387 | keepRule = !!$( val.depends, element.form ).length;
|
|
1339 | 1393 | if ( keepRule ) {
|
1340 | 1394 | rules[ prop ] = val.param !== undefined ? val.param : true;
|
1341 | 1395 | } else {
|
1342 |
| - $.data( element.form, "validator" ).resetElements( $( element ) ); |
| 1396 | + $.data(element.form, "validator").resetElements($(element)); |
1343 | 1397 | delete rules[ prop ];
|
1344 | 1398 | }
|
1345 | 1399 | }
|
|
1358 | 1412 | } );
|
1359 | 1413 | $.each( [ "rangelength", "range" ], function() {
|
1360 | 1414 | var parts;
|
| 1415 | + |
1361 | 1416 | if ( rules[ this ] ) {
|
1362 | 1417 | if ( Array.isArray( rules[ this ] ) ) {
|
1363 | 1418 | rules[ this ] = [ Number( rules[ this ][ 0 ] ), Number( rules[ this ][ 1 ] ) ];
|
|
1390 | 1445 | normalizeRule: function( data ) {
|
1391 | 1446 | if ( typeof data === "string" ) {
|
1392 | 1447 | var transformed = {};
|
| 1448 | + |
1393 | 1449 | $.each( data.split( /\s/ ), function() {
|
1394 | 1450 | transformed[ this ] = true;
|
1395 | 1451 | } );
|
|
1421 | 1477 |
|
1422 | 1478 | // Could be an array for select-multiple or a string, both are fine this way
|
1423 | 1479 | var val = $( element ).val();
|
| 1480 | + |
1424 | 1481 | return val && val.length > 0;
|
1425 | 1482 | }
|
1426 | 1483 | if ( this.checkable( element ) ) {
|
|
1489 | 1546 | // https://jqueryvalidation.org/minlength-method/
|
1490 | 1547 | minlength: function( value, element, param ) {
|
1491 | 1548 | var length = Array.isArray( value ) ? value.length : this.getLength( value, element );
|
| 1549 | + |
1492 | 1550 | return this.optional( element ) || length >= param;
|
1493 | 1551 | },
|
1494 | 1552 |
|
1495 | 1553 | // https://jqueryvalidation.org/maxlength-method/
|
1496 | 1554 | maxlength: function( value, element, param ) {
|
1497 | 1555 | var length = Array.isArray( value ) ? value.length : this.getLength( value, element );
|
| 1556 | + |
1498 | 1557 | return this.optional( element ) || length <= param;
|
1499 | 1558 | },
|
1500 | 1559 |
|
1501 | 1560 | // https://jqueryvalidation.org/rangelength-method/
|
1502 | 1561 | rangelength: function( value, element, param ) {
|
1503 | 1562 | var length = Array.isArray( value ) ? value.length : this.getLength( value, element );
|
| 1563 | + |
1504 | 1564 | return this.optional( element ) || ( length >= param[ 0 ] && length <= param[ 1 ] );
|
1505 | 1565 | },
|
1506 | 1566 |
|
|
1535 | 1595 | // Number of digits right of decimal point.
|
1536 | 1596 | return match[ 1 ] ? match[ 1 ].length : 0;
|
1537 | 1597 | },
|
| 1598 | + decimals = 0, |
1538 | 1599 | toInt = function( num ) {
|
1539 | 1600 | return Math.round( num * Math.pow( 10, decimals ) );
|
1540 | 1601 | },
|
1541 |
| - valid = true, |
1542 |
| - decimals; |
| 1602 | + valid = true; |
1543 | 1603 |
|
1544 | 1604 | // Works only for text, number and range input types
|
1545 | 1605 | // TODO find a way to support input types date, datetime, datetime-local, month, time and week
|
|
1562 | 1622 |
|
1563 | 1623 | // Bind to the blur event of the target in order to revalidate whenever the target field is updated
|
1564 | 1624 | var target = $( param );
|
| 1625 | + |
1565 | 1626 | if ( this.settings.onfocusout && target.not( ".validate-equalTo-blur" ).length ) {
|
1566 | 1627 | target.addClass( "validate-equalTo-blur" ).on( "blur.validate-equalTo", function() {
|
1567 | 1628 | $( element ).valid();
|
|
1605 | 1666 | data: data,
|
1606 | 1667 | context: validator.currentForm,
|
1607 | 1668 | success: function( response ) {
|
1608 |
| - var valid = response === true || response === "true", |
| 1669 | + var valid = response === true || response === 'true', |
1609 | 1670 | errors, message, submitted;
|
1610 | 1671 |
|
1611 | 1672 | validator.settings.messages[ element.name ][ method ] = previous.originalMessage;
|
|
0 commit comments