Transfer
A transfer is used to make complex selections from a list of options.
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 or by double-clicking an option.
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
Selectinstead.
Options
For all the demo's below, transferOptions is an array of objects with the following shape:
;[
{
label: 'ANC 1st visit',
value: 'anc_1st_visit',
},
]
The onChange and selected properties are created like this:
const [selected, setSelected] = useState()
const onChange = (payload) => setSelected(payload.selected)
Header
<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
<Transfer
options={transferOptions}
selected={selected}
leftFooter={<Footer />}
onChange={onChange}
/>
The footer component is as follows:
<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
<Transfer
enableOrderChange
options={transferOptions}
selected={selected}
onChange={onChange}
/>
- Allow reordering if the order of the chosen options has meaning or consequences.
Filtering
<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
- Different types of data will need different loading strategies.
- Set the
loadingorloadingPickedprop totrueto block interaction with the transfer while loading is taking place.
Infinite/lazy loading
Load more options as a user scrolls down. Use the following props together:
loading: Set totruewhen fetching data,falsewhen complete.onEndReached: Called when the user scrolls to the end of the list or when the end of the list is already visible after theoptionsarray changes.selectedOptionsLookup: Provide a lookup object for selected items that aren't in the currentoptionsarray.
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
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
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 in the options array. Like when having options that lazy load or can be filtered async. | |
| selectedWidth | string | '320px' | ||
| sourceEmptyPlaceholder | node | |||
| onEndReached | function | |||
| onEndReachedPicked | function | |||
| onFilterChange | function | |||
| onFilterChangePicked | function |