How to use react-dual-listbox
Published: 2022-04-09 15:44:54

## What is react-dual-listbox?

React Dual Listbox is a lightweight React component for rendering dual listbox views. 

## Here is a minimal example on how to use react-dual-listbox

You can Install the library using your favorite dependency manager.
 **Using yarn:**

`yarn add react-dual-listbox`

**Using npm:**

`npm install react-dual-listbox --save`

Please, note that this library makes use of Font Awesome styles and expects them to be loaded in the browser.

## Styling react-dual-listbox

For your convenience, the library's styles can be consumed utilizing one of the following files:

- node_modules/react-dual-listbox/lib/react-dual-listbox.css

- node_modules/react-dual-listbox/src/less/react-dual-listbox.less

- node_modules/react-dual-listbox/src/scss/react-dual-listbox.scss

You can either include one of these files in your stylesheets or utilize a CSS loader. 
**Code sample:**

```
import 'react-dual-listbox/lib/react-dual-listbox.css';
```

## How to render Component

The `DualListBox` is a controlled component, so you have to update the `selected` property in conjunction with the `onChange` handler if you want the selected values to change.

**Here is a minimal code sample for rendering of the component:**

```
import React from 'react';
import DualListBox from 'react-dual-listbox';

const options = [
    { value: 'one', label: 'Option One' },
    { value: 'two', label: 'Option Two' },
];

class Widget extends React.Component {
    state = {
        selected: ['one'],
    };

    onChange = (selected) => {
        this.setState({ selected });
    };

    render() {
        const { selected } = this.state;

        return (
            <DualListBox
                options={options}
                selected={selected}
                onChange={this.onChange}
            />
        );
    }
}
```

## Optgroups is also supported

Note that, traditional `<optgroup>`'s are also supported.

**Code sample:**

```
render() {
    const options = [
        {
            label: 'Earth',
            options: [
                { value: 'luna', label: 'Moon' },
            ],
        },
        {
            label: 'Mars',
            options: [
                { value: 'phobos', label: 'Phobos' },
                { value: 'deimos', label: 'Deimos' },
            ],
        },
        {
            label: 'Jupiter',
            options: [
                { value: 'io', label: 'Io' },
                { value: 'europa', label: 'Europa' },
                { value: 'ganymede', label: 'Ganymede' },
                { value: 'callisto', label: 'Callisto' },
            ],
        },
    ];

    return <DualListBox options={options} />;
}
```

## Disabling Component or Options

Pass in the `disabled` property to disable the entire component. Alternatively, individual options may be disabled on a per-item basis.

**Code sample:**

```
render() {
    const options = [
        {
            label: 'Mars',
            disabled: true,
            options: [
                { value: 'phobos', label: 'Phobos' },
                { value: 'deimos', label: 'Deimos' },
            ],
        },
        {
            label: 'Jupiter',
            options: [
                { value: 'io', label: 'Io' },
                { value: 'europa', label: 'Europa', disabled: true },
                { value: 'ganymede', label: 'Ganymede' },
                { value: 'callisto', label: 'Callisto' },
            ],
        },
    ];

    return <DualListBox options={options} />;
}
```

## Filtering
You can enable filtering of available and selected options by merely passing in the `canFilter` property.

**Code sample:**

```
render() {
    ...

    return <DualListBox canFilter options={options} />;
}
```
Note that, you can also optionally override the default filter placeholder text and the filtering function.

**Code sample:**

```
render() {
    ...

    return (
        <DualListBox
            canFilter
            filterCallback={(option, filterInput) => {
                if (filterInput === '') {
                    return true;
                }

                return (new RegExp(filterInput, 'i')).test(option.label);
            }}
            filterPlaceholder="Filter..."
            options={options}
        />
    );
}
```
You can also control the filter search text, rather than leaving it up to the component.

**Code sample:**

```
render() {
    ...

    return (
        <DualListBox
            canFilter
            filter={{
                available: 'europa',
                selected: '',
            }}
            options={options}
            onFilterChange={(filter) => {
                console.log(filter;
            }}
        />
    );
}
```

## Action/Button Alignment

Note that, by default the movement buttons are aligned to the center of the component. Another option is to align these actions to be above their respective lists.

**Code Sample:**

```
render() {
    ...

    return (
        <DualListBox alignActions="top" options={options} />
    );
}
```

## Preserve Select Ordering

By default, `react-dual-listbox` will order any selected items according to the order of the `options` property. There may be times in which you wish to preserve the selection order instead. In this case, you can add the `preserveSelectOrder` property.

Note that, any `<optgroup>`'s supplied will not be surfaced when preserving the selection order.

**Code sample:**

```
render() {
    ...

    return <DualListBox options={options} preserveSelectOrder />;
}
```
To allow users to re-arrange their selections after moving items to the right, you may also pass in the `showOrderButtons` property.

## Restrict Available Options

Sometimes, it may be desirable to restrict what options are available for selection. For example, you may have a control above the dual listbox that allows a user to search for a planet in the solar system. Once a planet is selected, you want to restrict the available options to the moons of that planet. Use the `available` property in that case.

**Code sample:**

```
render() {
    ...
    
    // Let's restrict ourselves to the Jovian moons
    const available = ['io', 'europa', 'ganymede', 'callisto'];
    
    return <DualListBox options={options} available={available} />;
}
```

## Changing the Default Icons

By default, `react-dual-listbox` uses Font Awesome for the various icons that appear in the component. To change the defaults, simply pass in the icons property and override the defaults.

**Code sample:**

```
<DualListBox
    ...
    icons={{
        moveLeft: <span className="fa fa-chevron-left" />,
        moveAllLeft: [
            <span key={0} className="fa fa-chevron-left" />,
            <span key={1} className="fa fa-chevron-left" />,
        ],
        moveRight: <span className="fa fa-chevron-right" />,
        moveAllRight: [
            <span key={0} className="fa fa-chevron-right" />,
            <span key={1} className="fa fa-chevron-right" />,
        ],
        moveDown: <span className="fa fa-chevron-down" />,
        moveUp: <span className="fa fa-chevron-up" />,
        moveTop: <span className="fa fa-double-angle-up" />,
        moveBottom: <span className="fa fa-double-angle-down" />,
    }}
/>
```

## Extract Changed Values

At times, it may be useful to know which options the user highlighted when the selected values change. In this case, the second parameter of the `onChange` handler may be used.

**Code sample:**

```
class Widget extends React.Component {
    ...

    onChange = (selected, selection) => {
        console.log('The user highlighted these options', selection);
        this.setState({ selected });
    };
    
    ...
}
```


[Check the output here...](https://github.com/jakezatecky/react-dual-listbox/blob/HEAD/demo.gif)


Thanks for reading...

**Happy Coding!**