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.