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

Already on GitHub? Sign in to your account

Appearance of non-deterministic validation on empty required fields #146

Closed
syndicatedshannon opened this Issue Jul 9, 2011 · 12 comments

Comments

Projects
None yet
3 participants

**** ISSUE ****
The implementation 'lastElement' causes unpredictable results when validating empty fields. The interaction of cleared prior error messages further complicates. Finally, a successfully validated field (successList) does not receive the same frequency of validation as a previously invalidated field.

**** STEPS TO REPRODUCE ****
Use as an example the 'Remember The Milk' Form:
http://jquery.bassistance.de/validate/demo/milk/

  1. Tab or click into 'First Name' field. Enter text.
  2. Tab once or click into 'Last Name' field. Enter text.
  3. Shift-tab once or click into 'First Name' field. Clear text.
  4. Tab once or click into 'Last Name' field. Clear text.

**** EXPECTED RESULT ****
First Name and Last Name fields show invalid state.

**** ACTUAL RESULT ****
First Name shows valid state. Last Name shows invalid state.

**** OTHER USE CASES ****
I first really noticed this issue when validating a pre-filled (and then reloaded, as in a later edit of a profile) form. Fields that begin their life filled, even though they have passed the 'success' test and then been formatted accordingly, can have contents deleted and still visually appear valid.

**** COMMENTS ****
Looking at the code, I'm not certain what the intent was with 'lastElement', so I'm probably not the right party to make related adjustments. It appears to have been added to address a very specific issue. I also don't understand the intended difference between submitted[] and errorMap[], and some related topics.

I might recommend merely replacing the 'lastElement' check with a 'successList' membership check on keyup and focusout. If you want me to make that change, just shoot me an e-mail.

Shannon

For now, I've added in my own project:

|| $.inArray(element, this.successList)

to the event tests on lines 224 and 229 of jquery.validate.js, as follows:

    onfocusout: function(element) {
        if (!this.checkable(element) && (element.name in this.submitted || $.inArray(element, this.successList) || !this.optional(element))) {
            this.element(element);
        }
    },
    onkeyup: function(element) {
        if (element.name in this.submitted || $.inArray(element, this.successList) || element == this.lastElement) {
            this.element(element);
        }
    },

I'm still don't see what scenario lastElement covers.

lxa commented Jul 24, 2011

I second that.

btw your patch does not work, this one does (however its rather hack than patch):

onfocusout: function(element) {
    if (!this.checkable(element) && (element.name in this.submitted || $(element).hasClass(this.settings.validClass) || !this.optional(element))) {
        this.element(element);
    }
},
onkeyup: function(element) {
    if (element.name in this.submitted || $(element).hasClass(this.settings.validClass) || element == this.lastElement) {
        this.element(element);
    }
},

@ixa: Hmmm, it works for me in the cases I experienced... could you let me know what happened to you so I know what to expect? There was no change?

p.s. I told ya I wasn't the right person to fix it ;)

lxa commented Jul 25, 2011

Well I doubt it works at least because JQuery.inArray returns -1 on failure, not 0. :)
Even if this is fixed, successList is not stored between calls (at least in jquery.validate 1.8.1 at least) - and is always empty in these events.
So I guess your code was just always true (-1 to be precise), and this was fine for you (re-validation on each and every event) - but this defeats the purpose of lastElement - 'lazy validation'. ;)

re: inArray; yeah, I always do that. thank you.

this.successList = $.grep( this.successList, function(element) { return !(element.name in errors);
// only removes items that are now in error state (which are then also validated as we desire
reset: function() { this.successList = [];
// is only run at times I desire success list cleared anyway

What am I overlooking that causes it not to be stored?
Thank you.

lxa commented Jul 25, 2011

element > prepareElement > reset for example

LOL, crazytalk ;) I'm stealing your hack.

lxa commented Jul 25, 2011

Help yourself.))

Contributor

mlynch commented Apr 24, 2012

See #396

Contributor

mlynch commented Apr 25, 2012

Duplicate of #244

@mlynch mlynch closed this Apr 25, 2012

This defect note lists steps-to-reproduce that aren't documented in #244, namely:

  1. Forms where there are no option boxes, like the Remember the Milk link in the description
  2. Forms that begin their life filled and have validation forced

If you want to wait and mark it "fixed", I'll test those two scenarios at that time.

Shannon

Alternately, I'll leave myself a note to test this issue when #244 is closed.

@kay-jay kay-jay added a commit to kay-jay/jquery-validation that referenced this issue Jun 24, 2014

@kay-jay kay-jay Hack from jquery-validation#146 1507feb
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment