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

feat: fail on first invalid #102

Open
shawnheide opened this issue Feb 2, 2023 · 5 comments · May be fixed by #111
Open

feat: fail on first invalid #102

shawnheide opened this issue Feb 2, 2023 · 5 comments · May be fixed by #111

Comments

@shawnheide
Copy link

Hi again, I'm migrating a project using the jquery validation package and am having a hard time finding solutions to a few things. One of the things I'm trying to setup is a field with a required rule, a regexp rule, and a call axios to check uniqueness. Is it possible to fail on the first invalid rule?

The only thing I found so far was checking the context in the Promise function, but the problem with that is that the error message is for the last rule (the axios rule in this case), instead of the first invalid rule. Thanks for your time and help.

@shawnheide
Copy link
Author

So I found that if I resolve(true) if it's invalid that it works how I want. It's a little bit cumbersome though to check context in the promise function. Any thoughts on how to make this cleaner?

validator: (value, context) => () => {
    return new Promise((resolve) => {
        if (!context["#field"].isValid) {
            return resolve(true);
        }
        axios
            .post("/url", {field: "value"})
            .then((response) => {
                return resolve(response.data.success);
            })
            .catch((error) => resolve(false));
    });
  },```

@horprogs
Copy link
Owner

horprogs commented Feb 3, 2023

Hm, you mean validator function triggers even if the previous rules failed? I guess it's a bug then. I will look into that, but in meanwhile I think you workaround is not bad.

@shawnheide
Copy link
Author

I've been digging around and trying to figure out the differences from jquery-validation package that I'm moving from. One of the issues is that the rules are run in reverse order (I'm assuming so that the message is shown from the first rule). The problem with this is that I can't stop my custom rule from running if the field isn't valid and also have the message be the rule that is failing.

Just in case, here's an example where the validator promise wouldn't skip since it evaluates first, but outputs "The field is required".

validator.addField("#basic_email", [
    {
        rule: "required",
    },
    {
        rule: "email",
    },
    {
        validator: (value, fields) => () =>
            new Promise((resolve) => {
                if (!fields["#basic_email"].isValid) {
                    return resolve(false);
                }
                return resolve(true);
            }),
        errorMessage: "Email already exists!",
    },
]);

If you invert the rules, the promise runs is skipped, but the message if from the validator function.

validator.addField("#basic_email", [
    {
        validator: (value, fields) => () =>
            new Promise((resolve) => {
                if (!fields["#basic_email"].isValid) {
                    return resolve(false);
                }
                return resolve(true);
            }),
        errorMessage: "Email already exists!",
    },
    {
        rule: "email",
    },
    {
        rule: "required",
    },
]);

Making that work seems like it would require a decent amount of refactoring, so I just wanted to see what your thoughts are on it, before starting on a PR. Hopefully I'm just missing something obvious that you can correct me on. Thanks for your time.

@shawnheide shawnheide linked a pull request Feb 15, 2023 that will close this issue
@shawnheide
Copy link
Author

Another option would be to keep things the same, drop the field reversal and stop on the first invalid rule, which I believe is similar to how jquery-validation does it. I tested this with my setup and it seems to work. I also created a PR if that's helpful.

@ceciiiron
Copy link

ceciiiron commented Jul 12, 2023

I am also working on the same email validation and I think this is a bug. I want to check first if the email field has value.

validator.addField('#email', [{
    validator: (value, context) => () => {
        return new Promise((resolve) => {
            if (context["#email"].isValid) {
                axios.get("/users/search?email=" + value).then(response =>
                    resolve(false)
                ).catch(err =>
                    resolve(true)
                )
            }
             return resolve(false);
        })
    },
    errorMessage: 'Email already exists!',
}, {
    rule: 'required',
}, ])

The code below works but:
on first validation run, the error message is "Email already exists" but it should be "The field is required" (It doesn't run the promise tho). Now if I enter some character and I empty the input field, the message "The field is required" shows.

Recording.2023-07-12.235302.mp4

The bug is also visible on the docs. I think @shawnheide's pull request solves the issue, however I cannot modify the core files of this package because I am only using cdn in my current setup.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants