Skip to content

Import#

import { Iterate } from '@dnb/eufemia/extensions/forms'
render(<Iterate.EditContainer />)

Description#

Iterate.EditContainer enables users to toggle (with animation) the content of each item between the Iterate.ViewContainer and this edit container. It can be used instead of the Iterate.AnimatedContainer.

Relevant links#

By default, it features the Iterate.Toolbar containing a "Done" button and a "Cancel" button. The "Cancel" button resets any changes made to the item content, restoring it to its original state.

import { Iterate, Field, Value } from '@dnb/eufemia/extensions/forms'
render(
<Iterate.Array>
<Iterate.EditContainer
title="Edit account holder"
titleWhenNew="New account holder"
>
<Field.Name.Last itemPath="/name" />
</Iterate.EditContainer>
<Iterate.ViewContainer title="Account holder">
<Value.Name.Last itemPath="/name" />
</Iterate.ViewContainer>
</Iterate.Array>
)

The item number in the title#

You can use the {itemNo} variable in the title or the titleWhenNew property to display the current item number.

import { Iterate, Field, Value } from '@dnb/eufemia/extensions/forms'
render(
<Iterate.Array>
<Iterate.EditContainer
title="Edit account holder {itemNo}"
titleWhenNew="New account holder {itemNo}"
>
<Field.Name.Last itemPath="/name" />
</Iterate.EditContainer>
</Iterate.Array>
)

Get the internal item object#

You can get the internal item object by using the Iterate.useItem hook.

import { Iterate, Field, Value } from '@dnb/eufemia/extensions/forms'
const MyItemForm = () => {
// TypeScript type inference
const item = Iterate.useItem<{ foo: string }>()
console.log('My item:', item.index, item.value.foo)
return <Field.String itemPath="/" />
}
render(
<Iterate.Array value={['foo', 'bar']}>
<MyItemForm />
</Iterate.Array>
)

Customize the Toolbar#

import { Iterate, Field } from '@dnb/eufemia/extensions/forms'
render(
<Iterate.Array>
<Iterate.EditContainer>
<Field.Name.Last itemPath="/name" />
<Iterate.Toolbar>
<Iterate.EditContainer.DoneButton />
<Iterate.EditContainer.CancelButton />
</Iterate.Toolbar>
</Iterate.EditContainer>
</Iterate.Array>
)

Variants#

minimumOneItem#

This variant has the following behavior:

  • When EditContainer is visible, and the number of items in the array is one, the entire toolbar will be hidden.
import { Iterate } from '@dnb/eufemia/extensions/forms'
render(
<Iterate.Array>
<Iterate.EditContainer toolbarVariant="minimumOneItem">
Item Content
</Iterate.EditContainer>
</Iterate.Array>
)

Accessibility#

The Iterate.EditContainer component has an aria-label attribute, which is set to the title property value. It uses a section element to wrap the content, which helps users with screen readers to get the needed announcement.

When the edit container becomes active, it will automatically receive the active element focus. And when the edit container switches to the view container, the focus will be set to the view container.

Demos#

Accounts

Account holder 1

Fornavn
Tony
Etternavn
Rogers

const MyEditItemForm = () => {
  return (
    <Field.Composition>
      <Field.Name.First itemPath="/firstName" width="medium" />
      <Field.Name.Last itemPath="/lastName" width="medium" required />
    </Field.Composition>
  )
}
const MyEditItem = () => {
  return (
    <Iterate.EditContainer
      title="Edit account holder {itemNo}"
      titleWhenNew="New account holder {itemNo}"
    >
      <MyEditItemForm />
    </Iterate.EditContainer>
  )
}
const MyViewItem = () => {
  const item = Iterate.useItem()
  console.log('index:', item.index)
  return (
    <Iterate.ViewContainer title="Account holder {itemNo}">
      <Value.SummaryList>
        <Value.Name.First itemPath="/firstName" showEmpty />
        <Value.Name.Last itemPath="/lastName" placeholder="-" />
      </Value.SummaryList>
    </Iterate.ViewContainer>
  )
}
const CreateNewEntry = () => {
  return (
    <Iterate.PushContainer
      path="/accounts"
      title="New account holder"
      openButton={
        <Iterate.PushContainer.OpenButton text="Add another account" />
      }
      showOpenButtonWhen={(list) => list.length > 0}
    >
      <MyEditItemForm />
    </Iterate.PushContainer>
  )
}
const MyForm = () => {
  return (
    <Form.Handler
      data={{
        accounts: [
          {
            firstName: 'Tony',
            lastName: 'Rogers',
          },
        ],
      }}
      onChange={(data) => console.log('DataContext/onChange', data)}
      onSubmit={async (data) => console.log('onSubmit', data)}
    >
      <Flex.Stack>
        <Form.MainHeading>Accounts</Form.MainHeading>

        <Form.Card gap={false}>
          <Iterate.Array path="/accounts" animate>
            <MyViewItem />
            <MyEditItem />
          </Iterate.Array>

          <CreateNewEntry />
        </Form.Card>

        <Form.SubmitButton variant="send" />
      </Flex.Stack>
    </Form.Handler>
  )
}
render(<MyForm />)

Toolbar variant#

Minimum one item#

When having one item in the Iterate.Array:

View Content

When having two items in the Iterate.Array:

View Content

View Content

EditContainer with error#

Press the submit button to see the error.

Suggest an edit