Material UI — Transfer List

Image for post
Image for post
Photo by timJ on Unsplash

Material UI is a Material Design library made for React.

It’s a set of React components that have Material Design styles.

In this article, we’ll look at how to add a transfer list with Material UI.

Transfer List

A transfer list lets us move one or more items between lists.

To use it, we can write:

import React from "react";
import Grid from "@material-ui/core/Grid";
import List from "@material-ui/core/List";
import ListItem from "@material-ui/core/ListItem";
import ListItemIcon from "@material-ui/core/ListItemIcon";
import ListItemText from "@material-ui/core/ListItemText";
import Checkbox from "@material-ui/core/Checkbox";
import Button from "@material-ui/core/Button";
import Paper from "@material-ui/core/Paper";
function not(a, b) {
return a.filter(value => b.indexOf(value) === -1);
}
function intersection(a, b) {
return a.filter(value => b.indexOf(value) !== -1);
}
export default function App() {
const [checked, setChecked] = React.useState([]);
const [left, setLeft] = React.useState([0, 1, 2, 3]);
const [right, setRight] = React.useState([4, 5, 6, 7]);
const leftChecked = intersection(checked, left);
const rightChecked = intersection(checked, right);
const handleToggle = value => () => {
const currentIndex = checked.indexOf(value);
const newChecked = [...checked];
if (currentIndex === -1) {
newChecked.push(value);
} else {
newChecked.splice(currentIndex, 1);
}
setChecked(newChecked);
};
const handleAllRight = () => {
setRight(right.concat(left));
setLeft([]);
};
const handleCheckedRight = () => {
setRight(right.concat(leftChecked));
setLeft(not(left, leftChecked));
setChecked(not(checked, leftChecked));
};
const handleCheckedLeft = () => {
setLeft(left.concat(rightChecked));
setRight(not(right, rightChecked));
setChecked(not(checked, rightChecked));
};
const handleAllLeft = () => {
setLeft(left.concat(right));
setRight([]);
};
const customList = items => (
<Paper>
<List dense component="div" role="list">
{items.map(value => {
const labelId = `transfer-list-item-${value}-label`;
return (
<ListItem
key={value}
role="listitem"
button
onClick={handleToggle(value)}
>
<ListItemIcon>
<Checkbox
checked={checked.indexOf(value) !== -1}
tabIndex={-1}
disableRipple
inputProps={{ "aria-labelledby": labelId }}
/>
</ListItemIcon>
<ListItemText id={labelId} primary={`item ${value + 1}`} />
</ListItem>
);
})}
<ListItem />
</List>
</Paper>
);
return (
<Grid container spacing={2} justify="center" alignItems="center">
<Grid item>{customList(left)}</Grid>
<Grid item>
<Grid container direction="column" alignItems="center">
<Button
variant="outlined"
size="small"
onClick={handleAllRight}
disabled={left.length === 0}
aria-label="move all right"
>

</Button>
<Button
variant="outlined"
size="small"
onClick={handleCheckedRight}
disabled={leftChecked.length === 0}
aria-label="move selected right"
>
&gt;
</Button>
<Button
variant="outlined"
size="small"
onClick={handleCheckedLeft}
disabled={rightChecked.length === 0}
aria-label="move selected left"
>
&lt;
</Button>
<Button
variant="outlined"
size="small"
onClick={handleAllLeft}
disabled={right.length === 0}
aria-label="move all left"
>

</Button>
</Grid>
</Grid>
<Grid item>{customList(right)}</Grid>
</Grid>
);
}

We have a grid 2 lists side by side.

We added the list with the List component.

The left list is created with the customList component, which has a List with some items inside it.

Each item has its own checkbox so that's we can check them off and move them.

The moving is done by a few functions.

The handleAllRight function moves everything to the right.

handleCheckedRight moves everything that’s checked to the right.

handleCheckedLeft moves the items that are check to the left list.

handleAllLeft moves all items to the left list.

The move is done by a few helper functions.

setLeft and setRight sets the items for the left and right respectively.

We concatenate the existing items with the ones that’s checked in each function.

setChecked is used to set the checked value of each item.

It only unchecks that values that are moved.

The example is simplified from the one at https://material-ui.com/components/transfer-list/

Image for post
Image for post
Photo by Annie Spratt on Unsplash

Conclusion

We can make a transfer list by following the Material UI example.

We make 2 lists with their own items.

The items are on each list are determined by the state.

Then we can move them by concatenating to the new list and removing them from the old list.

Written by

Web developer. Subscribe to my email list now at http://jauyeung.net/subscribe/. Email me at hohanga@gmail.com

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store