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

Async validate() handlers not called when form does not need validation #99

Open
stefanfisk opened this issue Sep 17, 2024 · 5 comments
Assignees

Comments

@stefanfisk
Copy link

Laravel Precognition Plugin Version

0.5.7

Laravel Version

10.43

Plugin

Alpine

Description

The async validate() handlers are not called if the request is equal to the previous request.

If I understand everything correctly the root cause is that onBeforeValidation() short circuits the request.

As a workaround onBeforeValidation: () => true can be added to the validate() config.

Steps To Reproduce

Call the following code twice. The second time it will not output anything.

 this.form.validate({
    onSuccess: (response) => {
        console.log('onSuccess', response);
    },
    onValidationError: (response, axiosError) => {
        console.log('onValidationError', response, axiosError);
    },
});
@timacdonald
Copy link
Member

@stefanfisk, this is by design.

Could you outline the exact issue you are facing in your application?

@stefanfisk
Copy link
Author

@timacdonald I have two use cases where this has caused me issues, both for when the user submits the form.

The first use case is to focus the first input with an error. So when the user submits the form it is fully validated and then the first input with an error is focused. If the user tries to submit a second time without actually editing the form the same thing should happen again.

The second use case is a form where I want to perform a file upload to S3 before actually submitting the form. So my idea was to:

  1. Validate all fields
  2. If there are no errors, upload the files to S3
  3. Submit the form

The workaround with onBeforeValidation is fine for me since the number of extra requests should be low. But I was very confused when validate() sometimes simply did nothing and I could find no mention of this behavior in the changelog or pull request.

Unless I am mistaken your example with the Next button in #69 will also result in the button not actually doing anything on consecutive clicks. So if the user does not notice the first message about the form having validation errors the button is just dead until the user edits the form or does something else that triggers a validation so that the previous request no longer matches the next request.

@CodeWrap
Copy link

CodeWrap commented Oct 1, 2024

I am experiencing the same issue with the "laravel-precognition-vue-inertia" package. If I want to check the same request again, nothing happens unless I have onBeforeValidation: () => true.

My steps:

  • Click on nextStep—works fine.
  • Click on previousStep.
  • Click on nextStep again—nothing happens.
const nextStep = () => {
    form.touch([
        'private_email',
        'first_name',
        'middle_name',
        'last_name',
        'gender',
    ]).validate({
        onPrecognitionSuccess: () => {
            currentStep.value++;
        },
    });
};

const previousStep = () => {
    currentStep.value--;
};

@timacdonald
Copy link
Member

Appreciate the information. I can see there are a few related issues that mean our "wizard" form story is not ideal. I'm thinking on some ideas on how we can remedy this.

@Orclaus
Copy link

Orclaus commented Oct 9, 2024

Hours wasted on this, I was suspecting this was the cause but I thought it was my fault all the time.

I am using Alpine version. And confirm this workaround works:

form.touch([...]).validate({ onSuccess() => { ... }, onBeforeValidation: () => true });

This is only the way to do some kind of multi-step wizard, the example in the documentation does not work as it is right now.

Edit: If your user ever wants to go back on the wizard to change some data, if you touched some fields in the next steps, you need to 'untouch' them, but this method does not exist/is not exposed.

Therefore your best bet is to call form.reset(...currentStepFields); this will reset your current step's fields/attributes , so your user will have to input the data again, but then you are allowed to go back to a previous step. this is the only way to correctly go back, if you dont do that, the precognition request for the previous 'new' step will include the old step attributes as well (and if they are wrong, it wont validate so you cannot go to the next step)

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

No branches or pull requests

5 participants