When left blank, optional elements are silently counted as invalid #481

Closed
sbandyopadhyay opened this Issue Aug 15, 2012 · 5 comments

Projects

None yet

6 participants

The short version.
See the error for yourself: http://jsfiddle.net/r4F4L/

As noted in the documentation for numberOfInvalids(), one can provide callbacks for invalidHandler (or showErrors, etc.) that use numberOfInvalids() to summarize the total number of errors.

When an optional field (that is, any field using a validation method that calls this.optional(element)) is left blank, that field is counted as invalid, and numberOfInvalids() returns 1 greater than it would otherwise.

There is no error message displayed -- which is the desired functionality! -- but that means that this field is essentially counted as invalid silently.

How to replicate this error.
See it here live: http://jsfiddle.net/r4F4L/

Set up a form with a field that has just one rule: 'number'. (Note that this field is not required.)

Specify the showErrors parameter when setting up the validation, like so:

$('#myForm').validate({
  rules: {
    myField: 'number'
  },
  showErrors: function(errorMap, errorList) {
    console.debug('Number of errors: '+ this.numberOfInvalids());
    this.defaultShowErrors();
  }
});

Now enter a number for the field, so that it validates correctly. So far, so good.

Now delete the number out of the field. The console.debug() will print out the number 1, even though there is no error!!

Why this may be happening
this.optional(element) returns "dependency-mismatch" when the optional field is left blank.

number() returns "dependency-mismatch", because it got that from this.optional(element).

check() receives "dependency-mismatch" and then returns undefined as a result.

element() receives back undefined, and as a result marks this element as invalid.

Issues this may be related to?
#37: depency-mismatch

CWSpear commented Aug 28, 2012

I have this same issue, and came up with pretty much the same conclusion.

I do believe it's related to #37. My issue was calling the .valid() function on a particular set of elements when some of they were required dependent on the value of a dropdown.

I am working on a quick demo and will post it soon.

CWSpear commented Aug 28, 2012

Here's my fiddle: http://jsfiddle.net/FhNrD/2/

So the fields state, province and region are only required if the country is US, Canada, and neither of those respectively. Normally I'd hide the ones not required, but I'm showing everything for this demo.

The reason I'm using .valid() is because it's a multipart form and I want to validate just that section before moving on, so I want to only run valid on the elements in that block and not submit the form or anything.

If you fill out the form, choose US as the country, fill out state but leave region and province blank, it SHOULD alert "success," but even though it doesn't display errors (meaning somewhere in the logic, it does recognize that they aren't required in this situation), when you run .valid() on those elements, they return 0 (I would expect they would return 1).

While related (I think the same principle is at play, but it's a different method that gets called that's causing my issue, I believe), here's what I'm seeing:

Tracing it back for province (which shouldn't be required since country is not Canada), required() class depend() (link).

In there. it will see that it's a boolean (my function evals as a boolean, and and return false, which means Canada is not the currently selected country). Thus required() returns "dependency-mismatch" on the next line and that means I eventually end up with true & undefined in the valid() function I called, which is always 0.

I get that undefined because valid() calls element() that calls check() and you would expect check() to return a boolean, but if there is a dependency mismatch, it doesn't.

I would expect it to return that it's not required, not that it's not valid, or maybe check() should handle dependency mismatch better, maybe to the level that it returns SOMETHING that the other functions (like valid()) can handle...?

In terms of a solution if Line 529 returns true instead of undefined, it works like I would expect. I don't know where else that might affect the code, though.

I can also reproduce it easily. Is this going to be fixed?

@nschonni nschonni added the Bug label May 23, 2014
dankrz commented Sep 2, 2014

I've found partial workaround. I clean the invalid messanges before the validation in the onkeyup method.

        form.validate({
          onkeyup: function () {
            cleanupBeforeValidation(form);
            form.valid();
          },

From the check method.
505 // if a method indicates that the field is optional and therefore valid,
506 // don't mark it as valid when there are no other rules
------------------------------- important comment
507 if ( result == "dependency-mismatch" ) {
508 dependencyMismatch = true;
509 continue;
510 }

So if the method min/max which uses optional method and returns "dependency-mismatch" it assumens it is not assumed that validation succeeded but my need was to clear the massages on success method. I do it before.

Collaborator

I'm sorry for the lack of activity on this issue. Instead of leaving it open any longer, I decided to close old issues without trying to address them, to longer give the false impression that it will get addressed eventually.

To the reporter (or anyone else interested in this issue): If you're affected by the same issue, consider opening a new issue, with a testpage that shows the issue. Even better, try to fix the issue yourself, and improve the project by sending a pull request. This may seem daunting at first, but you'll likely learn some useful skills that you can apply elsewhere as well. And you can help keep this project alive. We've documented how to do these things, too. A patch is worth a thousand issues!

@jzaefferer jzaefferer closed this Jun 26, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment