Core: Validation fails to trigger when next field is already filled out

This change fix the bug when used with remote rule, it's already fixed
with other rules in commit 737630e788

Ref #1508
This commit is contained in:
Brahim Arkni
2016-01-18 15:25:23 +00:00
parent 40dae365ed
commit 7d74fc4157
3 changed files with 106 additions and 34 deletions

View File

@@ -289,7 +289,7 @@ $.extend( $.validator, {
if ( event.which === 9 && this.elementValue( element ) === "" || $.inArray( event.keyCode, excludedKeys ) !== -1 ) { if ( event.which === 9 && this.elementValue( element ) === "" || $.inArray( event.keyCode, excludedKeys ) !== -1 ) {
return; return;
} else if ( element.name in this.submitted || this.isValidElement( element ) ) { } else if ( element.name in this.submitted || element.name in this.invalid ) {
this.element( element ); this.element( element );
} }
}, },
@@ -487,6 +487,7 @@ $.extend( $.validator, {
if ( $.fn.resetForm ) { if ( $.fn.resetForm ) {
$( this.currentForm ).resetForm(); $( this.currentForm ).resetForm();
} }
this.invalid = {};
this.submitted = {}; this.submitted = {};
this.prepareForm(); this.prepareForm();
this.hideErrors(); this.hideErrors();
@@ -539,18 +540,6 @@ $.extend( $.validator, {
return this.size() === 0; return this.size() === 0;
}, },
// Check if the given element is valid
// return
// true If the field is valid
// false If the field is invalid
// undefined If the field is not validated yet.
//
// Note that this method assumes that you have
// already called `validate()` on your form
isValidElement: function( element ) {
return this.invalid[ element.name ] === undefined ? undefined : !this.invalid[ element.name ];
},
size: function() { size: function() {
return this.errorList.length; return this.errorList.length;
}, },
@@ -1431,7 +1420,7 @@ $.extend( $.validator, {
validator.prepareElement( element ); validator.prepareElement( element );
validator.formSubmitted = submitted; validator.formSubmitted = submitted;
validator.successList.push( element ); validator.successList.push( element );
delete validator.invalid[ element.name ]; validator.invalid[ element.name ] = false;
validator.showErrors(); validator.showErrors();
} else { } else {
errors = {}; errors = {};

View File

@@ -388,7 +388,6 @@ test( "rules(), normalizer", function() {
equal( v.numberOfInvalids(), 0, "All elements are valid" ); equal( v.numberOfInvalids(), 0, "All elements are valid" );
equal( v.size(), 0, "All elements are valid" ); equal( v.size(), 0, "All elements are valid" );
equal( v.isValidElement( urlc[ 0 ] ), true, "The url element should be valid" );
// Validate the lastname element, which will throw an exception // Validate the lastname element, which will throw an exception
throws( function() { throws( function() {

View File

@@ -48,6 +48,19 @@ $.mockjax( {
} }
} ); } );
$.mockjax( {
url: "issue1508.php",
response: function( settings ) {
if ( /abc/i.test( settings.data.val2 ) ) {
this.responseText = "false";
} else {
this.responseText = "true";
}
},
responseStatus: 200,
responseTime: 1
} );
// Asserts that there is a visible error with the given text for the specified element // Asserts that there is a visible error with the given text for the specified element
QUnit.assert.hasError = function( element, text, message ) { QUnit.assert.hasError = function( element, text, message ) {
var errors = $( element ).closest( "form" ).validate().errorsFor( element[ 0 ] ), var errors = $( element ).closest( "form" ).validate().errorsFor( element[ 0 ] ),
@@ -1473,31 +1486,102 @@ test( "don't revalidate the field when pressing special characters", function()
test( "#1508: Validation fails to trigger when next field is already filled out", function() { test( "#1508: Validation fails to trigger when next field is already filled out", function() {
// The next field is already filled out. // The next field is already filled out.
$( "#lastname" ).val( "something" ); $( "#box2" ).val( "something" );
var event = $.Event( "keyup", { keyCode: 9 } ), var event = $.Event( "keyup", { keyCode: 9 } ),
element = $( "#firstname" ), element = $( "#box1" ),
validator = $( "#testForm1" ).validate(); nextE = $( "#box2" ),
validator = $( "#testForm23" ).validate( {
rules: {
box1: {
required: true
},
box2: {
required: true
}
}
} ),
check = function( value ) {
// Fill the first element // Fill the first element
element.val( "abc" ); element.val( "something" );
// Tab to the next field // Tab to the next field
element.blur(); element.blur();
$( "#lastname" ).trigger( event ); nextE.trigger( event );
$( "#lastname" ).focus(); nextE.focus();
// Tab back to element // Tab back to element
$( "#lastname" ).blur(); nextE.blur();
element.trigger( event ); element.trigger( event );
element.focus(); element.focus();
// Delete the content // Change the content
element.val( "" ); element.val( value );
element.trigger( "keyup" ); element.trigger( "keyup" );
},
eq = function( expected, msg ) {
equal( validator.numberOfInvalids(), expected, "There is only one invalid element." );
equal( validator.invalidElements()[ 0 ], element[ 0 ], msg );
};
// 'element' should be invalid check( "" );
equal( validator.isValidElement( element[ 0 ] ), false, "The element is not valid" ); eq( 1, "The box1 element should be invalid" );
} );
test( "[Remote rule] #1508: Validation fails to trigger when next field is already filled out", function( assert ) {
assert.expect( 2 );
// The next field is already filled out.
$( "#val3" ).val( "something" );
var event = $.Event( "keyup", { keyCode: 9 } ),
element = $( "#val2" ),
nextE = $( "#val3" ),
done = assert.async(),
validator = $( "#testForm24" ).validate( {
rules: {
val2: {
remote: {
url: "issue1508.php"
}
},
val3: {
required: true
}
}
} ),
check = function( value ) {
// Fill the first element
element.val( "something" );
// Tab to the next field
element.blur();
nextE.trigger( event );
nextE.focus();
// Make sure all events will be called before the bellow code
setTimeout( function() {
// Tab back to element
nextE.blur();
element.trigger( event );
element.focus();
// Change the content
element.val( value );
element.trigger( "keyup" );
setTimeout( function() {
equal( validator.numberOfInvalids(), 1, "There is only one invalid element" );
equal( validator.invalidElements()[ 0 ], element[ 0 ], "The val2 element should be invalid" );
done();
} );
} );
};
check( "abc" );
} ); } );
test( "validate checkbox on click", function() { test( "validate checkbox on click", function() {