---
title: "Transfer"
description: "A transfer is used to make complex selections from a list of options."
url: https://developers.dhis2.org/docs/ui/components/transfer
source: https://github.com/dhis2/developer-portal/edit/main/docs/ui/components/transfer.md
---

# Transfer

A transfer is used to make complex selections from a list of options.

[Interactive demo: transfer--single-selection](https://developers.dhis2.org/demo/?path=/story/transfer--single-selection)

## Usage

A transfer is made up of two lists. The _source list_ that shows the available options and the _picked list_ that shows the chosen options. Options can be transferred between lists with the middle buttons, by double-clicking an option, or by dragging an option to the other list.

### When to use

- **Choose from many items**. Use a transfer if a user needs to choose from many items. Transfers can work for hundreds of thousands of items.
- **Ordered selections**. Use a transfer if chosen options need to have a specific order.
- **Choose from several groups**. Use a transfer if a user needs to choose from several groups into a single set of chosen options.

### When not to use

- **Choosing from a few items**. Don't use a transfer to choose from a few options. Use a [`Select`](https://developers.dhis2.org/docs/ui/components/select.md) instead.

## Options

For all the demo's below, `transferOptions` is an array of objects with the following shape:

```js
;[
    {
        label: 'ANC 1st visit',
        value: 'anc_1st_visit',
    },
]
```

The `onChange` and `selected` properties are created like this:

```js
const [selected, setSelected] = useState()
const onChange = (payload) => setSelected(payload.selected)
```

### Header

[Interactive demo: transfer--header](https://developers.dhis2.org/demo/?path=/story/transfer--header)

```jsx
<Transfer
    options={transferOptions}
    selected={selected}
    leftHeader={<Header label="Available options" />}
    rightHeader={<Header label="Selected options" />}
    onChange={onChange}
/>
```

The `header` component in this case is a simple `h4` element.

- Use headers for titles that make it clear what the transfer options are.
- _Source list_ headers could also contain group filters.

### Footer

[Interactive demo: transfer--options-footer](https://developers.dhis2.org/demo/?path=/story/transfer--options-footer)

```jsx
<Transfer
    options={transferOptions}
    selected={selected}
    leftFooter={<Footer />}
    onChange={onChange}
/>
```

The footer component is as follows:

```jsx
<a
    href="#"
    style={{
        color: 'grey',
        padding: '8px 0',
        display: 'block',
    }}
>
    Reload list
</a>
```

- Use footers for actions that apply to a list, like _Reload items_.

### Reordering

[Interactive demo: transfer--reordering](https://developers.dhis2.org/demo/?path=/story/transfer--reordering)

```jsx
<Transfer
    enableOrderChange
    options={transferOptions}
    selected={selected}
    onChange={onChange}
/>
```

- Allow reordering if the order of the chosen options has meaning or consequences.

### Drag and drop

[Interactive demo: transfer--drag-and-drop](https://developers.dhis2.org/demo/?path=/story/transfer--drag-and-drop)

Options can always be dragged between the two lists with a pointer. Dragging a highlighted option drags the whole highlighted set. When `enableOrderChange` is set, the picked list can also be reordered by dragging, and options dropped onto it are inserted at the drop position; otherwise dropped options are appended at the end.

- Drag and drop is a pointer-only convenience. The action buttons and reordering buttons remain the keyboard-accessible way to transfer and reorder options.
- Disabled options can't be dragged.

### Filtering

[Interactive demo: transfer--filtered](https://developers.dhis2.org/demo/?path=/story/transfer--filtered)

```jsx
<Transfer
    filterable
    filterPlaceholder="Search for an option"
    options={transferOptions}
    selected={selected}
    onChange={onChange}
/>
```

- Use filtering to help a user find options in the _source list_.

### Loading

[Interactive demo: transfer--loading-source](https://developers.dhis2.org/demo/?path=/story/transfer--loading-source)

- Different types of data will need different loading strategies.
- Set the `loading` or `loadingPicked` prop to `true` to block interaction with the transfer while loading is taking place.

#### Infinite/lazy loading

[Interactive demo: transfer--infinite-loading](https://developers.dhis2.org/demo/?path=/story/transfer--infinite-loading)

Load more options as a user scrolls down. Use the following props together:

- `loading`: Set to `true` when fetching data, `false` when complete.
- `onEndReached`: Called when the user scrolls to the end of the list or when the end of the list is already visible after the `options` array changes.
- `selectedOptionsLookup`: Provide a lookup object for selected items that aren't in the current `options` array.

Server-side filtering is another common pattern. Use the `loading` and `selectedOptionsLookup` props together, since not all selected options will be present in the filtered options list. Server-side filtering can be combined with lazy loading.

## API Reference

### TransferOption

#### Usage

To use `TransferOption`, you can import the component from the `@dhis2/ui` library  

```js
import { TransferOption } from '@dhis2/ui'
```

#### Props

|Name|Type|Default|Required|Description|
|---|---|---|---|---|
|label|node||*||
|value|string||*||
|className|string||||
|dataTest|string|``'dhis2-uicore-transferoption'``|||
|disabled|boolean||||
|highlighted|boolean||||
|onClick|function||||
|onDoubleClick|function||||

### Transfer

#### Usage

To use `Transfer`, you can import the component from the `@dhis2/ui` library  

```js
import { Transfer } from '@dhis2/ui'
```

#### Props

|Name|Type|Default|Required|Description|
|---|---|---|---|---|
|options|`arrayOf(\{<br/>  "label": "string",<br/>  "value": "string",<br/>  "disabled": "boolean"<br/>})`||*||
|onChange|function||*||
|addAllText|string||||
|addIndividualText|string||||
|className|string||||
|dataTest|string|``'dhis2-uicore-transfer'``|||
|disabled|boolean||||
|enableOrderChange|boolean||||
|filterCallback|function|``defaultFilterCallback``|||
|filterCallbackPicked|function|``defaultFilterCallback``|||
|filterLabel|string||||
|filterLabelPicked|string||||
|filterPlaceholder|string||||
|filterPlaceholderPicked|string||||
|filterable|boolean||||
|filterablePicked|boolean||||
|height|string|``'240px'``|||
|hideFilterInput|boolean||||
|hideFilterInputPicked|boolean||||
|initialSearchTerm|string|``''``|||
|initialSearchTermPicked|string|``''``|||
|leftFooter|node||||
|leftHeader|node||||
|loading|boolean||||
|loadingPicked|boolean||||
|maxSelections|number|``Infinity``|||
|optionsWidth|string|``'320px'``|||
|removeAllText|string||||
|removeIndividualText|string||||
|renderOption|function|``(option) => <TransferOption {...option} />``|||
|rightFooter|node||||
|rightHeader|node||||
|searchTerm|string||||
|searchTermPicked|string||||
|selected|`arrayOf(string)`|``[]``|||
|selectedEmptyComponent|node||||
|selectedOptionsLookup|objectOf|``{}``||To be used in scenarios where selected options may not be present<br/>in the options array. Like when having options that lazy load or can<br/>be filtered async.|
|selectedWidth|string|``'320px'``|||
|sourceEmptyPlaceholder|node||||
|onEndReached|function||||
|onEndReachedPicked|function||||
|onFilterChange|function||||
|onFilterChangePicked|function||||
