From eb88df0e635b19703dc60bbd7728537cc7b13cc9 Mon Sep 17 00:00:00 2001 From: Kieran Date: Mon, 4 Apr 2022 13:29:44 +0100 Subject: [PATCH] Core: wait for pendingRequests to finish before submitting form (#2369) --- src/core.js | 2 +- test/test.js | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/src/core.js b/src/core.js index b505e3588..c66f7584a 100644 --- a/src/core.js +++ b/src/core.js @@ -1109,7 +1109,7 @@ $.extend( $.validator, { } delete this.pending[ element.name ]; $( element ).removeClass( this.settings.pendingClass ); - if ( valid && this.pendingRequest === 0 && this.formSubmitted && this.form() ) { + if ( valid && this.pendingRequest === 0 && this.formSubmitted && this.form() && this.pendingRequest === 0 ) { $( this.currentForm ).submit(); // Remove the hidden input that was used as a replacement for the diff --git a/test/test.js b/test/test.js index 80fb69864..298df0dbc 100644 --- a/test/test.js +++ b/test/test.js @@ -80,6 +80,15 @@ $.mockjax( { } } ); +$.mockjax( { + url: "stop-request-submit-form.php", + response: function() { + $( "input[name='username']" ).val( "foobar" ); // Simulate input data changing before request finishes. + this.responseText = "true"; // Data is valid. + }, + responseTime: 1 +} ); + // Asserts that there is a visible error with the given text for the specified element QUnit.assert.hasError = function( element, text, message ) { var errors = $( element ).closest( "form" ).validate().errorsFor( element[ 0 ] ), @@ -2688,3 +2697,51 @@ QUnit.test( "addMethod, reusing remote in custom method", function( assert ) { e.val( "john.doe@gmail.com" ); assert.strictEqual( v.element( e ), true, "still invalid, because remote validation must block until it returns; dependency-mismatch considered as valid though" ); } ); + +QUnit.test( "stopRequest() should submit the form once pendingRequests === 0", function( assert ) { + var $form = $( "#userForm" ); + var button = $( ":submit", $form )[ 0 ]; + var done = assert.async(); + var v = $form.validate( { + debug: true, + rules: { + username: { + remote: "stop-request-submit-form.php" + } + } + } ); + var i = 1; + + // Register a `submit` event after the one registered by this plugin + $form.on( "submit", function() { + + // Ignoring the first submit that was triggered manually by clicking + // the submit button. The first submit will be aborted by this plugin + // in order to wait for `remote` method to finish validating the input + if ( i > 0 ) { + i--; + return false; + } + + // The second submit is the one triggered by `stopRequest()` after the + // `remote` method has finished processing its attached input. + + // Compare the button with the `submitButton` property + assert.deepEqual( + v.submitButton, button, "The submitButton property should be the same as button" + ); + + var hidden = $form.find( "input:hidden" )[ 0 ]; + assert.deepEqual( hidden.value, button.value ); + assert.deepEqual( hidden.name, button.name ); + + done(); + + return false; + } ); + + $( "input[name='username']", $form ).val( "something" ); + + // Submit the form + $( button ).click(); +} );