Fieldsets

With fieldsets you can build truly modular forms. Each fieldset you create, contains a config for it's fields and a render function which creates the output, like a Form does. Additionally you can define parameters for each fieldset, which are than computed and fed to the config and render functions.

In the example form below, we've created a simple date range input made out of two date fields. The fieldset has a parameter required which defines if the fields are required or not. We additionality highlight the state of the parameter with background colors (red for required). The dateRange fieldset is than used in the form three times, in the root of the form, in a group and in a collection with one entry.

<Form
    data={data}
    fields={fields}
    fieldsets={{
        dateRange: {
            params: {
                required: {
                    type: "boolean",
                    required: false,
                    default: true
                }
            },
            config: ({ params }) => {
                return [
                    {
                        id: "from",
                        label: "From",
                        type: "date",
                        isRequired: params.required
                    },
                    {
                        id: "to",
                        label: "To",
                        type: "date",
                        isRequired: params.required
                    }
                ];
            },
            render: ({ fieldProps, params }) => {
                return (
                    <div className="pure-g" style={{ background: params.required ? "#ffeeee" : "transparent" }}>
                        <div className="pure-u-1-3">{fieldProps.fields.from}</div>
                        <div className="pure-u-1-3">{fieldProps.fields.to}</div>
                    </div>
                );
            }
        }
    }}
    config={{
        fields: () => {
            return [
                {
                    id: "range",
                    label: "Date range",
                    type: "dateRange",
                    params: {
                        required: false
                    }
                },
                {
                    id: "grouprange",
                    label: "Group range",
                    type: "group",
                    fields: [
                        {
                            id: "range",
                            label: "Date range",
                            type: "dateRange",
                            params: {
                                required: true
                            }
                        }
                    ]
                },
                {
                    id: "collectionrange",
                    label: "Collection range",
                    type: "collection",
                    init: true,
                    min: 1,
                    fields: [
                        {
                            id: "range",
                            label: "Date range",
                            type: "dateRange"
                        }
                    ]
                }
            ]
        }
    }}
    render={({ actionProps, fieldProps }) => (
        <>
            <div>
                {fieldProps.fields.range}
                <br />
                {fieldProps.fields.grouprange.range}
                <br />
                {fieldProps.fields.collectionrange ? fieldProps.fields.collectionrange[0].range : null}
            </div>
            <br />
            <HR isDirty={fieldProps.isDirty} />
            <br />
            <button
                type="button"
                onClick={() => actionProps.handleActionClick(payload => console.log("onSubmit:", payload), true)}
            >
                Submit
            </button>
        </>
    )}
    onChange={payload => setData(payload)}
/>

You can of course store fieldsets in separate files and reuse them in different forms. The params object sets up default values for the params and does some additional type checking which is used in the console to warn devs on wrong uses of a fieldset.

There are a few reserved field types you are not allowed to use. These are collection, group, subform, fieldset and config.

Additionally, you should avoid using types you've defined in your fields, as those would be overwritten.

Related Demo