ciscoheat / sveltekit-superforms

Making SvelteKit forms a pleasure to use!
https://superforms.rocks
MIT License
2.15k stars 65 forks source link

Clearing form errors on client validation #141

Closed austerj closed 1 year ago

austerj commented 1 year ago

Hi there, love Superforms, what an awesome package!

During client-side validation, I noticed that form errors assigned by setError(form, null, '...') don't get cleared until a second form submission.

Maybe it makes sense that the errors returned by the server don't get cleared by default, but I'm wondering if there is a more elegant solution here to automatically clear the form errors upon the next client-side validation? For my use case, I have some server-side errors during a login process that I want to report to the user ("Wrong email or password", "Unknown error" etc.) in a label that is not attached to any individual form element, but I still want these to get cleared as soon as the user modifies the form again so the form validation returns to the client.

Is there a nice way of accomplishing this with Superforms without having to implement some "funky" workarounds or assigning the form errors to an arbitrary field?

https://stackblitz.com/edit/sveltekit-superforms-bug-reporting-r4oqyt?file=src%2Froutes%2F%2Bpage.svelte

austerj commented 1 year ago

A simple way to get the behavior I want is to just manually set $errors._errors = undefined on every input / blur event on each form element. For my context this is totally fine, but maybe not the prettiest solution if someone is dealing with very large forms. :D

ciscoheat commented 1 year ago

Hi, thank you, glad you like Superforms! You can do what you ask by subscribing to form and clearing the errors there, something like:

form.subscribe(() => {
  $errors._errors = undefined
})
ciscoheat commented 1 year ago

Or maybe it's better to use the tainted store:

tainted.subscribe($tainted => {
  if($tainted) $errors._errors = undefined
})

One of these should do it!

austerj commented 1 year ago

Hi, thanks for your reply!

Subscribing to the form seems to make the form error not show at all in the MRE. Subscribing to tainted seemed to work at first glance, but when I used it in my project the form error would again not show at all.

After some digging I realized it's probably because I clear the password before sending it back from the server, which seems to trigger the tainted reactivity to immediately clear the form error?

For my use case, clearing the form error on with on:input and on:blur do the trick and seem to be the most direct path to get the desired behavior (show the form error until the user interacts with the form directly again). I kept running into issues trying to make it work via reacting on tainted and ended up finding some quite strange behavior with the form errors, even without trying to do any manual overwrites.

I will open a separate issue covering those points, since those would anyways be blockers for a general way to get the desired behavior (clear form errors only when the user directly interacts with a form element).

ciscoheat commented 1 year ago

This one seems to be fixed with v0.8.7, and I hope #142 is too.

ciscoheat commented 1 year ago

Closing this, as it won't be applicable in 1.0. Use refine/superRefine to set form-level errors, instead of setMessage.