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

Query - Field values in tabbed UIs

Open h4xmd opened this issue 1 year ago • 5 comments

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.

h4xmd avatar Jun 22 '23 04:06 h4xmd

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.

fabian-hiller avatar Jun 22 '23 08:06 fabian-hiller

@h4xmd were you able to solve the problem?

fabian-hiller avatar Jun 23 '23 15:06 fabian-hiller

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.

h4xmd avatar Jun 25 '23 11:06 h4xmd

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 with reset, 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 avatar Jun 25 '23 14:06 ghalle

@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

fabian-hiller avatar Jun 25 '23 15:06 fabian-hiller