Skip to content

Description

Iterate.Array works in many ways similar to field-components. It has a value-prop that can receive an array or you can give it a path if you want it to retrieve an array from a surrounding DataContext. All children components of Iterate.Array are rendered once per element the array-value consists of.

Individual values and dynamic paths

Since Iterate.Array renders its children once per element, the field components inside must receive values based on the different elements in the array. This can be done in two ways:

1. elementPath

If field components inside Iterate.Array are given an elementPath prop, this will look for values based on the array element being the root of the structure, even if the array often comes from a surrounding data set. This means that you do not need to think about which index the field should point to, because it is handled by Iterate.Array internally. You can look at the individual element as its own structure.

2. Render props

If you want to be able to provide values to the individual field component directly instead of pointing to them with paths, you can give Iterate.Array a render prop. It works a bit like an array-map call. The render function receives the value of the element as the first argument, and the index of which element you are on as the second.

Examples of both the use of elementPath and Render Props in Iterate.Array can be found on demos.

Demos

Primitive elements

Code Editor
<Iterate.Array
  label="Array label"
  value={['Iron Man', 'Captain America', 'The Hulk']}
  onChange={(value) => console.log('onChange', value)}
>
  <Field.String elementPath="/" />
</Iterate.Array>

Object elements

Code Editor
<Iterate.Array
  label="Accounts"
  value={[
    {
      accountName: 'Brukskonto',
      accountNumber: '90901134567',
    },
    {
      accountName: 'Sparekonto',
      accountNumber: '90901156789',
    },
  ]}
  onChange={(value) => console.log('onChange', value)}
>
  <h3>
    <Value.String elementPath="/nickname" />
  </h3>
  <Layout.Row>
    <Field.BankAccountNumber elementPath="/accountNumber" />
    <Field.String label="Account name" elementPath="/accountName" />
  </Layout.Row>
</Iterate.Array>

Render props with primitive elements

Code Editor
<Iterate.Array
  label="Array label"
  value={['foo', 'bar', 'baz']}
  onChange={(value) => console.log('onChange', value)}
>
  {(elementValue) => <Field.String value={elementValue} />}
</Iterate.Array>

Render props with object elements

Code Editor
<Iterate.Array
  label="Array label"
  value={[
    {
      num: 1,
      txt: 'One',
    },
    {
      num: 2,
      txt: 'Two',
    },
    {
      num: 3,
      txt: 'Three',
    },
    {
      num: 4,
      txt: 'Four',
    },
  ]}
  onChange={(value) => console.log('onChange', value)}
>
  {({ num, txt }) => (
    <Layout.Row width="large">
      <Field.Number value={num} width="small" />
      <Field.String value={txt} width={false} />
    </Layout.Row>
  )}
</Iterate.Array>

With DataContext and add/remove buttons

elementPath points to the root of each iterated element, while path points to the root of the data source.

Avengers

Iron Man

Captain America

Code Editor
<Form.Handler
  data={{
    avengers: [
      {
        nickname: 'Iron Man',
        firstName: 'Tony',
        lastName: 'Stark',
        bornYear: 1970,
      },
      {
        nickname: 'Captain America',
        firstName: 'Steve',
        lastName: 'Rogers',
        bornYear: 1918,
      },
    ],
    alwaysThere: 'Nick Fury',
  }}
  onChange={(data) => console.log('Source onChange', data)}
>
  <Layout.MainHeading>Avengers</Layout.MainHeading>

  <Iterate.Array
    path="/avengers"
    onChange={(value) => console.log('Iterate onChange', value)}
  >
    <Layout.SubHeading>
      <Value.String elementPath="/nickname" />
    </Layout.SubHeading>

    <Layout.Row align="center">
      <Field.String
        elementPath="/firstName"
        width="medium"
        label="First name"
      />
      <Field.String
        elementPath="/lastName"
        width="medium"
        label="Last name"
      />
      <Field.Number
        elementPath="/bornYear"
        label="Year of birth"
        width="small"
      />
      <Iterate.ArrayRemoveElementButton icon={TrashIcon} />
    </Layout.Row>

    <Field.String path="/alwaysThere" top="x-small" />
  </Iterate.Array>

  <Iterate.ArrayPushButton
    top="small"
    text="Add another avenger"
    path="/avengers"
    pushValue={{}}
  />
</Form.Handler>

Properties

Standard data value component props

PropertyTypeDescription
classNamestring(optional) Outer DOM element class name
valuearray(optional) Source data value for the input
layoutstring(optional) Layout for the label and input. Can be horizontal or vertical
labelstring(optional) Field label to show above / before the input feature
labelDescriptionstring(optional) A more discreet text displayed beside the label (i.e for "(optional)")
labelSecondarystring(optional) Secondary information displayed at the end of the label line (i.e character counter)
placeholderstring(optional) Text showing in place of the value if no value is given
pathstring(optional) JSON Pointer for where the data for this input is located in the source dataset (when using DataContext)
infoError or string(optional) Info message shown below / after the input
warningError or string(optional) Warning message shown below / after the input
errorError(optional) Error message shown below / after the input
disabledboolean(optional) Set true to show the field but without the possibility of changing the value.
emptyValueany(optional) The value to use (in onChange events etc) when emptying the field. Makes it possible for instance to provide undefined instead of an empty string when clearing the content of a text input.
requiredboolean(optional) When set true, the input will give an error if the value cannot be empty.
schemaobject(optional) Custom JSON Schema for validating the value.
validateInitiallystring(optional) Set true to show validation based errors initially (from given value-prop or source data) before the user interacts with the field.
validateUnchangedstring(optional) Set true to show validation based errors when the field is touched (like focusing a field and blurring) without having changed the value. Since the user did not introduce a new error, this will apply when the value was initially invalid based on validation.
continuousValidationstring(optional) Set true to show validation based errors continuously while writing, not just when blurring the field.
errorMessagesobject(optional) Custom error messages for each type of error, overriding default messages.
validatorfunction(optional) Custom validator function that will be called for every change done by the user. Can be asynchronous or synchronous.
onBlurValidatorfunction(optional) Custom validator function that will be called when the user leaves the field (blurring a text input, closing a dropdown etc). Can be asynchronous or synchronous.
toInputfunction(optional) Derivate called when the received / active value is sent to the input. Can be used for casting, changing syntax etc.
fromInputfunction(optional) Derivate called when changes is made by the user, to cast or change syntax back to the original (opposite of toInput).
PropertyTypeDescription
spacingstring or false(optional) How much space between sub components. Can be medium, small or false for no spacing.
widthstring or false(optional)false for no width (use browser default), small, medium or large for predefined standard widths, stretch for fill available width.

Events

EventDescription
onChange(optional) Will be called on value changes made by the user, with the new value as argument.
onFocus(optional) Will be called when the component gets into focus. Like clicking inside a text input or opening a dropdown. Called with active value as argument.
onBlur(optional) Will be called when the component stop being in focus. Like when going to next field, or closing a dropdown. Called with active value as argument.