Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error messages reset with remote-validation #2150

Closed
archer3cl opened this issue Mar 6, 2018 · 14 comments · Fixed by #2242
Closed

Error messages reset with remote-validation #2150

archer3cl opened this issue Mar 6, 2018 · 14 comments · Fixed by #2242

Comments

@archer3cl
Copy link

Subject of the issue

Error messages resets after remote validation when using the ".valid()" method

Your environment

  • version of jquery-validate: v1.17.0
  • which browser and its version: Chrome latest

Steps to reproduce

  1. Build a form with a remote validation and other simple validations
  2. Call the ".valid()" method on the form

Expected behaviour

It should show the error messages on the corresponding fields

Actual behaviour

It resets the error messages on all the fields
gif
*If I call ".valid()" a second time, it shows the error messages correctly

@Arkni
Copy link
Member

Arkni commented Mar 16, 2018

Thanks a lot for filling this issue! I'll triage and take a look at it as soon as possible!

@Arkni Arkni added the Remote label Mar 16, 2018
@Discartyptics
Copy link

Discartyptics commented Apr 10, 2018

@Arkni, it looks like it possibly has something to do with validator.resetInternals(); being fired in the "success" section of the remote rule, which is clearing the errorMap variable.
Possibly related to #1907 ?

@morrow95
Copy link

Here for the same reason and came across this post. I will try to describe the behavior with this example :

rules are :
name : required
date : remote

Form loads with no value for 'name' input - the 'date' input has a valid value. I submit the form and the following happens in this order :

highlight: function
unhighlight: function
remote post for the date input
unhighlight: function called again

At this point, visually, the 'name' input does not have error classes added to it through the highlight: function even though it should being invalid. Although, the 'errorPlacement: function' has run successfully and I have an error message shown for it.

If I submit a second time the following happens :

highlight: function
unhighlight: function

and everything is correct (the highlight: function correctly added classes to the 'name' input for being invalid). The only difference here is the remote post and the unhighlight : function after it were not executed because its value never changed - it didn't need to validate.

I'll also add, if I view the DOM live, on the initial submit I can see the correct classes are applied to the 'name' input through the highlight: function and then immediately disappear.

From what I can tell... it works as it should then the remote post validation happens and any invalid input (whatever was done with the highlight : function) immediately gets reversed when the remote post happens through the unhighlight: function.

Looking forward to a solution for this. Been using this plugin for a few years now and love it. I am changing on a few things on one of the sites I use this and noticed this problem happening with the 1.17.0 version.

@ETNyx
Copy link

ETNyx commented Jun 1, 2018

I have got just same issue as moeeow95 describe highlight -> unhighlight -> remote -> unhighlight
And as Discartyptics point remote clear some errorlist so fast bypass for user can be like:

highlight: function (element) {
	$(element).closest('.form-group').addClass('has-error');
},
unhighlight: function (element) {
	if ($(element).hasClass('is-valid-class')) {
		$(element).closest('.form-group').removeClass('has-error');
	}
},
success: function(lebel, element) {
	$(element).addClass('is-valid-class');
},

@morrow95
Copy link

morrow95 commented Jun 9, 2018

Can we get an update on this? This is a major flaw as it currently stands.

@anufrien
Copy link

anufrien commented Jul 16, 2018

@morrow95 @ETNyx
i found this bug and i have a fix. You right this bug only for method "remote" or other methods inherited from "remote" method

before

invalidElements: function() {
    return $( this.errorList ).map( function() {
        return this.element;
    } );
},

after

invalidElements: function() {
    var
        v = this,
        invalid = $.extend( {}, v.invalid ),
        $elements = $( [] );
    $.each( invalid, function( key, value ) {
        if ( value !== false && invalid.hasOwnProperty( key ) ) {
            $elements = $elements.add( v.findByName( key ) );
        }
    } );
    return $elements;
};

Merhod "remote" call

validator.resetInternals();
->
   reset validator.errorList
   ->
      validator.showErrors()
      ->
         validator.defaultShowErrors()
         ->
            if ( this.settings.unhighlight ) {
              for ( i = 0, elements = this.validElements(); elements[ i ]; i++ ) {
                 ...
              }
           }
           ->
             validator.validElements
             ->
                validator.invalidElements: function() {
                  return $( this.errorList ).map( function() {
                    return this.element;
                  } );
                }

and clean all errors

anufrien added a commit to anufrien/jquery-validation that referenced this issue Jul 16, 2018
@morrow95
Copy link

Good stuff. Looking forward to this getting pushed in a new release. Thanks!

@felipesales007
Copy link

SOLUÇÃO NA LINHA COMENTADA //validator.resetInternals(); (SÓ COMENTAR ELA) file: (jquery.validate.js)

remote: function( value, element, param, method ) {
if ( this.optional( element ) ) {
return "dependency-mismatch";
}

method = typeof method === "string" && method || "remote";

var previous = this.previousValue( element, method ),
    validator, data, optionDataString;

if ( !this.settings.messages[ element.name ] ) {
    this.settings.messages[ element.name ] = {};
}
previous.originalMessage = previous.originalMessage || this.settings.messages[ element.name ][ method ];
this.settings.messages[ element.name ][ method ] = previous.message;

param = typeof param === "string" && { url: param } || param;
optionDataString = $.param( $.extend( { data: value }, param.data ) );
if ( previous.old === optionDataString ) {
    return previous.valid;
}

previous.old = optionDataString;
validator = this;
this.startRequest( element );
data = {};
data[ element.name ] = value;
$.ajax( $.extend( true, {
    mode: "abort",
    port: "validate" + element.name,
    dataType: "json",
    data: data,
    context: validator.currentForm,
    success: function( response ) {
        var valid = response === true || response === "true",
            errors, message, submitted;

        validator.settings.messages[ element.name ][ method ] = previous.originalMessage;
        if ( valid ) {
            submitted = validator.formSubmitted;
            //validator.resetInternals(); <- bug form validate remote
            validator.toHide = validator.errorsFor( element );
            validator.formSubmitted = submitted;
            validator.successList.push( element );
            validator.invalid[ element.name ] = false;
            validator.showErrors();
        } else {
            errors = {};
            message = response || validator.defaultMessage( element, { method: method, parameters: value } );
            errors[ element.name ] = previous.message = message;
            validator.invalid[ element.name ] = true;
            validator.showErrors( errors );
        }
        previous.valid = valid;
        validator.stopRequest( element, valid );
    }
}, param ) );
return "pending";

}

@afagard
Copy link

afagard commented May 13, 2020

if ($(element).hasClass('is-valid-class')) {

Was |--| close to moving to Parsley. Thank god I found this.

@golfmike
Copy link

This appears to still be an issue in v1.19.3 that was introduced in v1.15.0.

As mentioned above by Discartyptics on Apr 10, 2018, this is the exact issue reported in issue #1907 back in 2016 by thinking2. validator.resetInternals(); SHOULD NOT be fired in the "success" section of the remote rule which is resulting in the clearing of the errorMap/errorList variables.

Does anybody actually maintain this code anymore? This issue was reported 6 years ago and the exact fix for it identified 5 years ago.

@bytestream
Copy link
Member

@golfmike send a PR.

@JasonTheProgrammer
Copy link

Was there a reason #2191 wasn't merged?

It looks like #2242 tries to address the same issue, but in a much more succinct way - by just removing the call to resetInternals in the remote success handler.

They've both passed checks, but seem to have stalled at the review stage.

@ghost
Copy link

ghost commented Jan 20, 2023

Hi,

I'm trying to add a unit test to the PR #2242 (initially opened by @leonardospina ) to get it validated.
But I have a problem, I didn't managed to write an example that doesn't work. I have a few cases in the project I'm working on that show the same behaviour but they don't seem to have the same origin than this issue.

@archer3cl Have you a demo project that show the issue ? I tried to build one and tried to produce the issue by calling the .valid() function, but it didn't show the issue

ghost pushed a commit to leonardospina/jquery-validation that referenced this issue Jan 23, 2023
@ghost
Copy link

ghost commented Jan 23, 2023

I managed to write a case that fail and the test

bytestream pushed a commit that referenced this issue Jan 24, 2023
…2242)

* Core: Call to resetInternals removed in remote validation callback

* Core: Add unit test for issue #2150 fix

* Core: fix code style errors

Co-authored-by: leonardospina <leo@babieleo.it>
Co-authored-by: Julien Tschäppät <julien.tschappat@smartliberty.ch>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.