Closed taffit closed 2 years ago
From how initialValues
is being used internally, making it a store would be a bit impractical. From your requirements, do you only need to reset the touched
store to false when the Reset
button is clicked? If that's so, would keeping track of your new initialValues
outside of Felte work?
Currently, a way I see to reset your form to new initialValues
could look something like this:
// This can mutate due to an external action
let initialValues = { /* Your initial values */};
const { reset, setFields } = createForm({
initialValues,
/* ... */
});
// This could act as your `reset` function
function resetForm() {
// We reset the whole form
reset();
// We set the form's values to its new `initialValues`
setFields(initialValues);
}
Regarding your last point, the previous call to setFields
should be able to set the re-calculated date.
Is there something I missed/misunderstood from your issue? Felte's API has grown quite big so I'm hesitant to increasing said API even more if it's not absolutely necessary.
Thank you @pablo-abc for commenting. I will try what your solution and check if it fits our needs and will report back.
To clarify your questions: Setting just the $touched
-state is not enough. When resetting or comparing it should be able to refer to the latest initialValues
. These are initially set during the creation of the form, but when these need to be updated, then the new values should be used. E. g. a form is shown to the user with initial values. The user changes some values and submits the form. The data is sent to the backend and saved. The user changes some fields and hits the reset button. Now the values/$data
must be set back to the values when the form was submitted, not the ones used during the creation of the form.
Handling the initialValues
outside of Felte is an option, of course (I'm doing this currently). But this results in more code in each component to handle these, instead of letting the form-component/Felte let handle this.
Instead of providing a store, maybe a method like setFields()
, but for initial values (setInitialValues()
)?
I will report back once I tried your proposed solution.
Hello @pablo-abc , so I tried your mentioned solution, but unfortunately it didn't work. I need the initial values somehow to set during form creation as well as when the backend processed the entries. As these are not available via Felte, I created and handle them outside of Felte. setFields()
does what it says, and this works, but when resetting, the initial values are set again instead of the updated initialValues. So I'm using now my own reset-method.
As I have another problem right now (in combination with @imask/svelte
: somehow the events overlay each other, so that the masking overwrites the current value instead of "extending" of what is in the input-field right now), I'm afraid that I need to turn to some other form-library (svelte-formula
has the same problem, btw).
So from my side this issue can be closed now.
Hey, @taffit ! Thanks for giving Felte a try. Regarding the initial values issue, I guess I'm not seeing how handling this within Felte would remove complexity from your requirements. Is this more or less what you're referring to about resetting the form to different "initialValues"?
If initialValues
were a store (or if a method to change it would be exposed) I guess I don't see much difference on the work you'd have to do from handling it outside of Felte with a custom reset form:
// This would be reactive regardless
let initialValues = {};
const { form } = createForm({ initialValues });
To handling it within Felte:
// Assuming it is a store
const { form, initialValues } = createForm({ initialValues: {} });
Your logic outside of Felte would need to be almost the same regardless of if Felte handles it internally or not. Specially since your validation requirements (comparing current values with latest initialValues) seem, at least to me, as a bit of a special case scenario.
Regarding imask
, you're not the first person to open an issue regarding this. This is a scenario on which in order to guarantee no race conditions with Felte I have dabbled around making a package integrating vanilla imask
. (E.g. maybe a @felte/imask
package). Anyway this is something I'll need to explore more in-depth at a future date. Thanks for your input, it serves a lot for improving Felte!
@pablo-abc You are probably right about the initialValues. I just thought that it might be slightly simpler if I can refer to the initialValues from Felte when comparing (as it contains initialValues already), but you are absolutely right: there is not much difference.
I created a REPL to illustrate my problem/intention, however as $touched
seems to not work on the REPL (or more probable: I'm just too dumb ;-)), I couldn't finish it. Strangely also the isFormTouched
doesn't work on the REPL while working fine locally. As it is only half-finished, take it with caution. But maybe it clarifies some questions.
It's comforting that even experienced developers have problems in combination with imask. Feeling a little less stupid now :-)
Whatever, thank you @pablo-abc for the prompt responses and @loremaps for the quick implementation of my needs. I was very impressed on how such feature requests were handled, as well as the whole Felte library, which IMHO is a very mature, complete and feature full one to handle forms with svelte. Felt at home immediately ;-).
(Fwiw, I try to revert now to svelte-use-form
, which suffers from some other problems, but at least in combination with imask I didn't experience any problems. Hopefully I'm remembering this one correctly ;-))
Thank you for such a wonderful library!
I've experienced that, depending on the packages you use, CodeSandbox works better than the REPL sometimes. I'll check it out.
Regarding the touched
part. The function of the touched
store is just to let you know if the user has interacted with the field. On text/number/email/etc inputs this means focusing + blurring, on other inputs just interacting with it. Unless I'm not understanding correctly, the comparison to your new initial values would better be handled within the validation process rather than with the touched
store?
Anyway, thanks a lot for taking your time to answer to my follow up questions! It's really appreciated!
Sorry, @pablo-abc , but I am now back at Felte again ;-). Just wanted to tell you about my findings regarding imask
(which I will post in the related issue as well).
After reverting to svelte-use-form
, I experienced the same problems there in combination with @imask/svelte
. As I remembered that I had it working there, I continued experimenting.
What doesn't work: Having imask as action (as @imask/svelte
provides) on the input-element in combination with some other library that accesses the field/events of the element. I experimented a bit with the events and the action, as e. g. adding an on:focus
which invokes the sometimes mentioned IMask.updateValue()
, but to no avail. And I'm also too noob on the frontend site to invest more time on this.
What does work, though:
initialValues
on form creation.onMount
to the elementThis way it seems that imask got the value updated (I experienced some other quirks after resetting the form, but that may be my fault, i. e. parts of the mask reflect the former modifications. E. g. the field contains 1.000
(masked) -> I change it to 231.000
(masked) -> Reset -> 1.000
-> I add 987
on the head of the number -> 9.8731.000
, i. e. the 3
from the previous edit is added. May be my fault, though).
What helps in this case with svelte-use-form
is, that it contains a store with all the html-elements of the form. This way you can easily iterate and e. g. attach a mask or similar. That would be maybe useful also for Felte (or is there a way to iterate the form-controls that I didn't find yet?)
Regarding your proposal for moving the check for changed values to the validation: imo this is something different. Let me clarify my intention/idea behind all this. I want to make some forms as idiot-user-proof ( ;-) ) as possible while hopefully being as user-friendly as possible.
But maybe I just pretend too much from the frontend :-) .
Tl;dr: Moving back to Felte as I found a workaround for the imask-problem
Edit: For completeness sake, a working REPL hopefully showing what I want is available here. It works fine, there is just so much to add in order to make it work. We have defaultData, initialData, initialValues (containing the (partly formatted) initialData), element-bindings and masks for each input.
For some form handling, we need to read AND set the initial values as well. Examples:
$data
-store) to the initial value.Reset
-button, these new values must be set in the form. Therefore we need to set theinitialValues
outside of the form initialization.In order to be able to do this, providing the
initialValues
as a store similar to$data
and$touched
would be a tremendous improvement for us.