svelte-forms icon indicating copy to clipboard operation
svelte-forms copied to clipboard

[REQUEST] Manually mark field as dirty

Open eden-omb opened this issue 3 years ago • 5 comments

Currently, a field is marked as dirty only when its value has changed; but I want it to be marked dirty when its been focused.

eden-omb avatar Jan 20 '22 12:01 eden-omb

Hi @eden-omb,

Currently, svelte-forms takes dirty just as a "change" of value indeed. The meaning of the keyword carries this behavior. As for now, I currently don't think changing a field state to dirty when the element is focused would be a great changed because we would need to link the HTML element to the field, which is not possible today and I would prefer to avoid that.

But we might consider adding a new use:touched which could add a touched state that can either

  • be triggered by the on:focus JS event
  • manually set by a callback defined by the user (custom form elements from other libraries for exemple).

Could be worth talking about the case, any thoughts?

chainlist avatar Jan 26 '22 16:01 chainlist

I'm curious regarding the use-case of setting a field dirty when it is focused, maybe you can elaborate real quick @eden-omb ?

seriousManual avatar Jan 27 '22 19:01 seriousManual

To me setting a field as dirty is not quite what we want.

We could do the same as Angular does with their forms: Adding a touched state.

In addition to that we could also infer a pristine state that would be dirty === false && touched === false that will that the user never touched and changed the value (manually or programmatically from the code).

But as mentioned, this would require to link the HTML element to the field object, which could make more difficult to use the library.

And today, one of the main advantage of svelte-forms in my opinion is its ease of use.

chainlist avatar Jan 27 '22 21:01 chainlist

I agree manually setting a field as dirty is a less-than-perfect solution, but it's the best one I had that wouldn't require svelte-forms to link to the HTML element.

The problem is with when to validate what. Currently, svelte-forms offers no way to validate a field once it's been touched, and to me this is a core functionality of a forms helper. My idea for manually setting a field as dirty is so that I can trigger validation on a per-field basis without svelte-forms having it bind to every input by default. This way I can simply bind validation when user touches a field or for whatever other reason without svelte-forms needing to implement a touched state, which would solve my problem just as well.

What do you propose? The way I see it, triggering validation on a field being exited without being changed is a core feature; this means that somewhere someone has to be able to bind to the HTML element. Perhaps a use:action that is passed a store that can be triggered from outside the field to trigger validation in it? I'm really not sure what would be the best way to solve this problem, but custom validation triggering is really fundamental for me. I'd be happy to build a PR once we agree on a design.

eden-omb avatar Jan 29 '22 15:01 eden-omb

Here's another use-case for manually marking as dirty or having a "touched" property as suggested.:

I want my form validation errors to be shown when the form is attempting to submit. Imagine a login form (name, password), and rather than filling out anything, I just click the "Submit" button. Now it's reasonable to expect an error on both the name and password field, as they're both empty, and should definitely not be.

The way that libraries such as Angular's Reactive Forms deal with this is by having a FormGroup.markAllAsTouched() method, and by showing validation errors if a control is dirty (and invalid).

With svelte-forms I don't think there currently isn't a good way to do this. And manually marking fields as dirty would solve that.

If the touched logic is something you'd want to have, I'd be happy to create a PR for it.

c00 avatar Jul 22 '22 10:07 c00