modular-forms
modular-forms copied to clipboard
Query - Field values in tabbed UIs
I seem to be stuck with a problem that's related to fetching field values using getValues()
where the fields exist multiple tabs in a UI.
The component in question has a number of child 'Pages' and each Page component has a Fields set on it. When the web app loads, only the components for the visible Field components are created.
Calling getValues() will then only return the values for the fields that are visible. Passing in options has no effect on the returned fields.
If however I call setValues() after creating the form, then getValues() almost returns all the fields in the form.
It seems to miss include all nested fields and any array fields.
I have to navigate to that tab to get the field to render before it is able to get fetched using getValues() or getValue().
The problem manifests itself in that I cannot load data into a form and then fetch all the fields unless they have been rendered which means I cannot skip tabs in the UI.
The alternative is to create 1 form per page which is terribly clunky.
Maybe the problem is related to the active
state: https://modularforms.dev/solid/guides/add-fields-to-form#active-state
If not, I would be happy if you provide me with a minimal reproduction, e.g. via StackBlitz, so that I can investigate the problem. Which frameworks do you use? I can provide you with a StackBlitz template.
@h4xmd were you able to solve the problem?
In the end I just used CSS styling (display: hidden) to show and hide all the relevant pages instead of using <Show/> so that way all the Fields were initialised on page load rather than as each page was shown.
I've encountered a similar issue trying to create a nested form where you have a list of character and you can click edit on one of the characters to bring up a form to edit that specific character.
It seems like a <Field>
has to have been created for a given field at least once for it to work correctly, from then on all the functionality related to that field seems to work correctly without that <Field>
existing.
Here's a list of things that don't work correctly before a corresponding <Field>
has been created once:
- Calling
getValues
with{ shouldActive: false }
, only fields that have had a corresponding<Field>
are included - Setting new
initialValues
withreset
, only fields that have had a corresponding<Field>
will have their value set.
I've created a basic example showing this: https://stackblitz.com/edit/github-e7ddxh?file=src%2Froutes%2Findex.tsx
Like @h4xmd mentioned in the comment above, a workaround is to always create the <Field>
and only hide it with CSS but this is not ideal and will not work if you ever need to call getValues
or reset
in your component before you return the JSX.
@ghalle unlike Qwik, SolidJS, Preact and React initialize the fields lazy. Which means that initial values does not need to be specified, unlike in Qwik. Technically we could change this and make it similar to Qwik.
getValues
can only deal with already initialized fields, as it does not have the necessary information to initialize fields itself. However, getValues
will be informed as soon as new fields are initialized, if it is executed in an effect or in the JSX code.
Instead of getValues
you should use getValue
to retrieve the value of a single field. getValue
is able to initialize fields and thus return initial values.
It is correct that reset
currently can only handle already initialized fields. I am trying to investigate the problem and find a solution. More about here: https://github.com/fabian-hiller/modular-forms/issues/87#issuecomment-1592635694