Demos#
Set data outside of the form#
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).
const existingData = { count: 1, } const Component = () => { const { data, update } = Form.useData('update-id', existingData) const increment = 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#
const existingData = { count: 1, } const Component = () => { const { data, update } = Form.useData('independent-id', existingData) const increment = useCallback(() => { update('/count', (count) => { return count + 1 }) }, [update]) return ( <Button onClick={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.
const MyForm = () => { const { data, reduceToVisibleFields } = Form.useData() // Use useEffect to ensure we get the latest data 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 is hidden.
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 />)