Demos
Set data outside of the form
Code Editor
const existingData = { foo: 'bar', } const Component = () => { const { data } = Form.useData('default-id', existingData) return ( <Form.Handler id="default-id"> <Field.String path="/foo" label={data.foo} /> </Form.Handler> ) } render(<Component />)
Update the data outside of the form
The update function update('/count', (count) => count + 1) has TypeScript support and returns the correct type for count (number).
Code Editor
const existingData = { count: 1, } const Component = () => { const { data, update } = Form.useData('update-id', existingData) const increment = React.useCallback(() => { update('/count', (count) => { return count + 1 }) }, [update]) return ( <Form.Handler id="update-id"> <Flex.Horizontal> <Field.Number path="/count" showStepControls /> <Form.SubmitButton onClick={increment} text={`Increment ${data.count}`} /> </Flex.Horizontal> </Form.Handler> ) } render(<Component />)
Shared state without a Form.Handler
Code Editor
const existingData = { count: 1, } const Component = () => { const { data, update } = Form.useData('independent-id', existingData) const increment = React.useCallback(() => { update('/count', (count) => { return count + 1 }) }, [update]) return ( <Button on_click={increment} text={`Increment ${data.count}`} variant="secondary" /> ) } render( <Flex.Vertical> <Component /> <Component /> </Flex.Vertical>, )
Get only data of visible fields
You can use the reduceToVisibleFields function to get only the data of visible (mounted) fields.
Code Editor
const MyForm = () => { const { data, reduceToVisibleFields } = Form.useData() // Use useEffect to ensure we get the latest data React.useEffect(() => { console.log( 'Result of reduceToVisibleFields: ', reduceToVisibleFields(data, { removePaths: ['/isVisible'], }), ) }, [data, reduceToVisibleFields]) return ( <Form.Handler> <Flex.Stack> <Field.Boolean label="Show radio buttons" variant="button" path="/isVisible" defaultValue={true} /> <Form.Visibility pathTrue="/isVisible" animate> <Field.Selection label="Radio buttons" variant="radio" path="/myValue" defaultValue="foo" > <Field.Option value="foo" title="Foo" /> <Field.Option value="bar" title="Bar" /> </Field.Selection> </Form.Visibility> <Value.Selection path="/myValue" inheritLabel inheritVisibility /> </Flex.Stack> </Form.Handler> ) } render(<MyForm />)
SyntaxError: Invalid or unexpected token
Filter your data
This example uses the keepInDOM property to keep the field in the DOM.
But with the filterData method we can filter out all fields that have the data-exclude-field attribute.
In this demo, the data-exclude-field attribute is added when the field are hidden.
Code Editor
const filterDataPaths = { '/isVisible': false, '/mySelection': ({ data }) => data.isVisible, '/myString': ({ data }) => { return data.isVisible && data.mySelection === 'more' }, } const MyForm = () => { return ( <Form.Handler defaultData={{ isVisible: false, mySelection: 'less', myString: 'foo', }} > <Flex.Stack> <Field.Boolean label="Toggle visible" variant="button" path="/isVisible" data-exclude-field /> <Form.Visibility pathTrue="/isVisible" animate> <Field.Selection label="Choose" variant="radio" path="/mySelection" value="less" > <Field.Option value="less" title="Less" /> <Field.Option value="more" title="More" /> </Field.Selection> <Form.Visibility visibleWhen={{ path: '/mySelection', hasValue: 'more', }} animate > <Field.String label="My String" path="/myString" value="foo" /> </Form.Visibility> </Form.Visibility> <Output /> </Flex.Stack> </Form.Handler> ) } const Output = () => { const { data, filterData } = Form.useData() return ( <> <Tools.Log data={filterData(filterDataPaths)} label="Filtered:" /> <Tools.Log data={data} label="All data:" /> </> ) } render(<MyForm />)