Skip to content

Demos

Transform data on commit

Legg til ny hovedkontaktperson

Code Editor
const MyForm = () => {
  return (
    <Form.Handler
      onChange={console.log}
      defaultData={{
        contactPersons: [
          {
            title: 'Hanne',
            value: 'hanne',
          },
        ],
        mySelection: 'hanne',
      }}
    >
      <Form.Card>
        <Form.SubHeading>Legg til ny hovedkontaktperson</Form.SubHeading>

        <HeightAnimation>
          <Field.Selection
            variant="radio"
            path="/mySelection"
            dataPath="/contactPersons"
          >
            <Field.Option title="Annen person" value="other" />
          </Field.Selection>
        </HeightAnimation>

        <Form.Visibility
          visibleWhen={{
            path: '/mySelection',
            hasValue: 'other',
          }}
          animate
        >
          <Flex.Stack>
            <Form.SubHeading>Ny hovedkontaktperson</Form.SubHeading>

            <Form.Isolation
              transformOnCommit={(isolatedData, handlerData) => {
                // Because of missing TypeScript support
                const contactPersons = handlerData['contactPersons']
                const newPerson = isolatedData['newPerson']
                return {
                  ...handlerData,
                  contactPersons: [
                    ...contactPersons,
                    {
                      ...newPerson,
                      value: newPerson.title.toLowerCase(),
                    },
                  ],
                }
              }}
              onCommit={(data, { clearData }) => {
                clearData()
              }}
              resetDataAfterCommit
            >
              <Flex.Stack>
                <Form.Section path="/newPerson">
                  <Field.Name.First required path="/title" />
                </Form.Section>

                <Form.Isolation.CommitButton />
              </Flex.Stack>
            </Form.Isolation>
          </Flex.Stack>
        </Form.Visibility>
      </Form.Card>
    </Form.Handler>
  )
}
render(<MyForm />)

Using the CommitButton

Code Editor
<Form.Handler
  onSubmit={(data) => console.log('onSubmit', data)}
  onChange={(data) => console.log('Regular onChange:', data)}
>
  <Flex.Stack>
    <Form.Isolation
      resetDataAfterCommit
      onChange={(data) => console.log('Isolated onChange:', data)}
    >
      <Flex.Stack>
        <Field.String required label="Isolated" path="/isolated" />
        <Form.Isolation.CommitButton text="Commit" />
      </Flex.Stack>
    </Form.Isolation>

    <Field.String
      required
      label="Committed from isolation"
      path="/isolated"
    />
    <Field.String required label="Outside of isolation" path="/regular" />

    <Form.SubmitButton />
  </Flex.Stack>
</Form.Handler>

Using commitHandleRef

Ny hovedkontaktperson

{
  "contactPersons": [
    {
      "title": "Hanne",
      "value": "hanne"
    }
  ]
} 
Code Editor
const MyForm = () => {
  const commitHandleRef = React.useRef(null)
  return (
    <>
      <Form.Handler
        bottom="large"
        data={{
          contactPersons: [
            {
              title: 'Hanne',
              value: 'hanne',
            },
          ],
        }}
      >
        <Form.Card>
          <Form.SubHeading>Ny hovedkontaktperson</Form.SubHeading>

          <HeightAnimation>
            <Field.Selection variant="radio" dataPath="/contactPersons" />
          </HeightAnimation>

          <Form.Isolation
            commitHandleRef={commitHandleRef}
            transformOnCommit={(isolatedData, handlerData) => {
              // Because of missing TypeScript support
              const contactPersons = handlerData['contactPersons']
              const newPerson = isolatedData['newPerson']
              const value = newPerson.title.toLowerCase()
              const transformedData = {
                ...handlerData,
                contactPersons: [
                  ...contactPersons,
                  {
                    ...newPerson,
                    value,
                  },
                ],
              }
              return transformedData
            }}
          >
            <Flex.Stack>
              <Form.Section path="/newPerson">
                <Field.Name.First required path="/title" />
              </Form.Section>
            </Flex.Stack>
          </Form.Isolation>
          <Tools.Log />
        </Form.Card>
      </Form.Handler>

      <button
        onClick={() => {
          commitHandleRef.current()
        }}
      >
        Commit from outside of handler
      </button>
    </>
  )
}
render(<MyForm />)

Inside a section

This example has a defaultValue both on the Form.Handler and the Form.Isolation.

When no defaultValue is set on the Form.Isolation (inner context), the default value from Form.Handler (outer context) is used for the initial value.

When pressing the "Legg til / Add"-button, the default value from Form.Isolation is inserted again, because resetDataAfterCommit is set to true.

Code Editor
<Form.Handler
  defaultData={{
    mySection: {
      isolated: 'Isolated value defined outside',
      regular: 'Outer regular value',
    },
  }}
  onChange={(data) => {
    console.log('Outer onChange:', data)
  }}
>
  <Form.Section path="/mySection">
    <Flex.Stack>
      <Form.Isolation
        defaultData={{
          isolated: 'The real initial "isolated" value',
        }}
        onPathChange={(path, value) => {
          console.log('Isolated onChange:', path, value)
        }}
        onCommit={(data) => console.log('onCommit:', data)}
        resetDataAfterCommit
      >
        <Flex.Stack>
          <Field.String label="Isolated" path="/isolated" required />
          <Form.Isolation.CommitButton />
        </Flex.Stack>
      </Form.Isolation>

      <Field.String label="Synced" path="/isolated" />
      <Field.String label="Regular" path="/regular" required />

      <Form.SubmitButton />
    </Flex.Stack>
  </Form.Section>
</Form.Handler>

Prevent uncommitted changes

This example uses the preventUncommittedChanges property to display an error message if the user has made changes and attempts to submit the form.

Try entering something in the input field, then submit the form. An error message will appear to indicate that changes must be committed first.

"undefined" 
Code Editor
<Form.Handler onSubmit={async (data) => console.log('onSubmit', data)}>
  <Flex.Stack>
    <Form.Isolation preventUncommittedChanges resetDataAfterCommit>
      <Flex.Stack>
        <Field.String required label="Isolated" path="/isolated" />

        <Flex.Horizontal>
          <Form.Isolation.CommitButton />
          <Form.Isolation.ResetButton showWhen="uncommittedChangeDetected" />
        </Flex.Horizontal>
      </Flex.Stack>
    </Form.Isolation>

    <Form.SubmitButton />

    <Tools.Log />
  </Flex.Stack>
</Form.Handler>

Update the data reference

This example shows how to update the data reference at a later point in time.

"undefined" 
Code Editor
const dataReference = Form.Isolation.createDataReference()
const SetDelayedData = () => {
  const { update } = Form.useData()
  React.useEffect(() => {
    setTimeout(() => {
      update('/isolated', 'With a delayed default value')
      dataReference.refresh() // <-- refresh the data reference
    }, 1000)
  }, [update])
  return null
}
render(
  <Form.Handler onSubmit={async (data) => console.log('onSubmit', data)}>
    <Flex.Stack>
      <Form.Isolation
        preventUncommittedChanges
        resetDataAfterCommit
        dataReference={dataReference}
      >
        <SetDelayedData />
        <Flex.Stack>
          <Field.String required label="Isolated" path="/isolated" />

          <Flex.Horizontal>
            <Form.Isolation.CommitButton />
            <Form.Isolation.ResetButton showConfirmDialog={false} />
          </Flex.Horizontal>
        </Flex.Stack>
      </Form.Isolation>

      <Form.SubmitButton />

      <Tools.Log />
    </Flex.Stack>
  </Form.Handler>,
)