Simple multi-select component for react-native (Select2 for react-native).
I've been super busy with work and other projects lately that I really don't have enough time to dedicate to this project. If you would like to maintain this project, you can drop me an email. Thanks.
$ npm install react-native-multiple-select --save
or use yarn
$ yarn add react-native-multiple-select
Note: Ensure to add and configure react-native-vector-icons to your project before using this package.
You can clone and try out the sample app or you can try sample
The snippet below shows how the component can be used
// import component
import React, { Component } from 'react';
import { View } from 'react-native';
import MultiSelect from 'react-native-multiple-select';
class MultiSelectExample extends Component {
state = {
demo1_SelectText: 'Demo 1 Field',
demo1_SelectedItems: [],
demo1_ItemsList: [{
id: '11',
name: 'Orange',
}, {
id: '12',
name: 'Apple',
}, {
id: '13',
name: 'Banana',
}, {
id: '14',
name: 'Tomato',
}],
demo2_SelectText: 'Demo 2 Field',
demo2_SelectedItems: [],
demo2_ItemsList: [{
id: '21',
name: 'Red',
}, {
id: '22',
name: 'Yellow',
}, {
id: '23',
name: 'White',
}, {
id: '24',
name: 'Blue',
}, {
id: '25',
name: 'Black',
}],
};
// // Call the action creator
demo1_OnSelectedItemsChange = (selectedItems) => {
console.log('demo1_OnSelectedItemsChange - SelectedItems: ', selectedItems);
// Add your code here for using the selcted value in your app
this.setState({
// To set the "selectText" prop to the selected value
// Can be useful for components with "single" selections (where the prop "single" is set)
demo1_SelectText: selectedItems[0],
});
};
demo1_OnAddItem = (newItemsList) => {
console.log('demo1_OnAddItem - newItemsList: ', newItemsList, ' - length: ', newItemsList.length);
// You can add your code here to add the newly added item to the original items list.
// 1. Removes the "LAST" element from the new items list. This the item, which was added by the user.
const lastElement = newItemsList.pop();
// 2. Adds the new element (which was extracted above) to the "TOP" of new items list.
// This makes it appear on top of the list. So, it is easier for the user to click on it.
newItemsList.unshift(lastElement);
// Note 1: The steps 1 & 2 (above) are optional.
// Note 2: Instead of 1 & 2 (above), it would have been better if entering a new value
// would result in selecting it without the need to select it from the list.
// Check [issue #110](https://github.com/toystars/react-native-multiple-select/issues/110)
this.setState({
demo1_ItemsList: newItemsList,
});
}
demo2_OnSelectedItemsChange = (selectedItems) => {
console.log('demo2_OnSelectedItemsChange - SelectedItems: ', selectedItems);
// Add your code here for using the selcted value in your app
this.setState({
// Use only for "multiple" selections (where the prop "single" is NOT set)
demo2_SelectedItems: selectedItems,
});
};
demo2_OnAddItem = (newItemsList) => {
console.log('demo1_OnAddItem - newItemsList: ', newItemsList, ' - length: ', newItemsList.length);
// You can add your code here to add the newly added item to the original items list.
// 1. Removes the "LAST" element from the new items list. This the item, which was added by the user.
const lastElement = newItemsList.pop();
// 2. Adds the new element (which was extracted above) to the "TOP" of new items list.
// This makes it appear on top of the list. So, it is easier for the user to click on it.
newItemsList.unshift(lastElement);
// Note 1: The steps 1 & 2 (above) are optional.
// Note 2: Instead of 1 & 2 (above), it would have been better if entering a new value
// would result in selecting it without the need to select it from the list.
// Check [issue #110](https://github.com/toystars/react-native-multiple-select/issues/110)
this.setState({
demo2_ItemsList: newItemsList,
});
}
render() {
return (
<View>
<View>
<MultiSelect
items={this.state.demo1_ItemsList}
uniqueKey="id"
displayKey="name"
selectText={this.state.demo1_SelectText}
searchInputPlaceholderText="Select or Type a value"
filterMethod="full"
single={true}
onSelectedItemsChange={this.demo1_OnSelectedItemsChange}
ref={(component) => { this.demo1_MultiSelect = component; }}
canAddItems={true}
onAddItem={this.demo1_OnAddItem}
/>
</View>
<View>
{this.demo1_MultiSelect && this.demo1_MultiSelect.getSelectedItemsExt(this.state.demo1_SelectedItems)}
</View>
<View>
<MultiSelect
items={this.state.demo2_ItemsList}
uniqueKey="name"
displayKey="name"
selectText={this.state.demo2_SelectText}
searchInputPlaceholderText="Select from the list below or Type a new one"
filterMethod="full"
single={false}
selectedItems={this.state.demo2_SelectedItems}
hideTags={false}
hideSubmitButton={false}
submitButtonText="OK"
onSelectedItemsChange={this.demo2_OnSelectedItemsChange}
ref={(component) => { this.demo2_MultiSelect = component; }}
canAddItems={true}
onAddItem={this.demo2_OnAddItem}
/>
</View>
<View>
{/* Istead of the prop "hideTags={false}" (above), you can use the following. */}
{/* {this.demo2_MultiSelect && this.licenceMultiSelect.getSelectedItemsExt(this.state.licenceSelectedItems)} */}
</View>
</View>
);
} // end of: render
} // end of: component
The component takes 3 compulsory props - items
, uniqueKey
and onSelectedItemsChange
. Other props are optional. The table below explains more.
Prop | Required | Purpose |
---|---|---|
altFontFamily | No | (String) Font family for searchInputPlaceholderText |
canAddItems | No | (Boolean) Defaults to "false". This allows a user to add items to the list of items provided. You need to handle adding the new items in the onAddItem function prop. Items may be added with the return key on the native keyboard. |
displayKey | No | (String) Defaults to "name". This string will be used to select the key to display the objects in the items array |
fixedHeight | No | (Boolean) Defaults to false. Specifies if select dropdown take height of content or a fixed height with a scrollBar (There is an issue with this behavior when component is nested in a ScrollView in which scroll event will only be dispatched to parent ScrollView and select component won't be scrollable). See this issue for more info. |
filterMethod | No | (String) Defaults to "partial". options: ["partial", "full"] Choose the logic on how the system filters items based on searchTerm. partial: checks all individual words and if at least one word matches will include that item. full: checks to ensure the item contains the full substring of searchterm in order minus any leading or trailing spaces. |
flatListProps | No | (Object) Properties for the FlatList. Pass any property that is required on the FlatList of the dropdown menu |
fontFamily | No | (String) Custom font family to be used in component (affects all text except searchInputPlaceholderText described above) |
fontSize | No | (Number) Font size for selected item name displayed as label for multiselect |
hideDropdown | No | (Boolean) Defaults false. Hide dropdown menu with a cancel, and use arrow-back |
hideSubmitButton | No | (Boolean) Defaults to false. Hide submit button from dropdown, and rather use arrow-button in search field |
hideTags | No | (Boolean) Defaults to false. Hide tokenized selected items, in case selected items are to be shown somewhere else in view (check below for more info) |
iconSearch | No | (Element, Object, boolean, Function) Element or functional component to change the Search Icon |
itemFontFamily | No | (String) Font family for each non-selected item in multi-select drop-down |
itemFontSize | No | (Number) Font size used for each item in the multi-select drop-down |
itemTextColor | No | (String) Text color for each non-selected item in multi-select drop-down |
items | Yes | (Array, control prop) List of items to display in the multi-select component. JavaScript Array of objects. Each object must contain a name and unique identifier (Check sample above) |
onAddItem | No | (Function) JavaScript function passed in as an argument. The function is called everytime a new item is added, and receives the entire list of items. Here you should ensure that the new items are added to your provided list of items in addition to any other consequences of new items being added. |
onChangeInput | No | (Function) JavaScript function passed in as an argument. The function is called everytime TextInput is changed with the value. |
onClearSelector | No | (Function) JavaScript function passeed in as an argument. The function is called everytime back button is pressed |
onSelectedItemsChange | Yes | (Function) JavaScript function passed in as an argument. The function is to be defined with an argument (selectedItems). Triggered when Submit button is clicked (for multi select) or item is clicked (for single select). (Check sample above) |
onToggleList | No | (Function) JavaScript function passed in as an argument. The function is called everytime the multiselect component is pressed |
searchInputPlaceholderText | No | (String) Placeholder text displayed in multi-select filter input |
searchInputStyle | No | (Object) Style object for multi-select input element |
selectText | No | (String) Text displayed in main component |
selectedItemFontFamily | No | (String) Font family for each selected item in multi-select drop-down |
selectedItemIconColor | No | (String) Color for selected check icon for each selected item in multi-select drop-down |
selectedItemTextColor | No | (String) Text color for each selected item in multi-select drop-down |
single | No | (Boolean) Toggles select component between single option and multi option |
styleDropdownMenu | No | (Style) Style the view of the dropdown menu |
styleDropdownMenuSubsection | No | (Style) Style the inner view of the dropdown menu |
styleInputGroup | No | (Style) Style the Container of the Text Input Group |
styleItemsContainer | No | (Style) Style the Container of the items that are displayed in a list |
styleListContainer | No | (Style) Style the Container of main list. See [this issue] (toystars#12) |
styleMainWrapper | No | (Style) Style the Main Container of the MultiSelector |
styleRowList | No | (Style) Style the Row that is displayed after you |
styleSelectorContainer | No | (Style) Style the Container of the Selector when user clicks on the dropdown |
styleTextDropdown | No | (Text Style) Style text of the Dropdown |
styleTextDropdownSelected | No | (Text Style) Style text of the Dropdown selected |
submitButtonColor | No | (String) Background color for submit button |
submitButtonText | No | (String) Text displayed on submit button |
tagBorderColor | No | (String) Border color for each selected item |
tagRemoveIconColor | No | (String) Color to be used for the remove icon in selected items list |
tagTextColor | No | (String) Text color for selected items list |
textColor | No | (String) Color for selected item name displayed as label for multiselect |
textInputProps | No | (Object) Properties for the Text Input. Pass any property that is required on the text input |
uniqueKey | Yes | (String) Unique identifier that is part of each item's properties. Used internally as means of identifying each item (Check sample below) |
selectedItems | No | (Array, control prop) List of selected items keys . JavaScript Array of strings, that can be instantiated with the component |
removeSelected | No | (Boolean) Filter selected items from list to be shown in List |
-
Tokenized selected items can be displayed in any other part of the view by adding a
ref
to theMultiSelect
component like soref={(component) => { this.multiSelect = component }}
. Then add this to any part of the screen you want the tokens to show up:this.multiSelect.getSelectedItemsExt(selectedItems)
. TheselectedItems
argument passed into the above mentioned method is the sameselectedItems
passed as the main component selected items prop. (See example above). -
If users shouldn't be able to select any of the items in the dropdown list, set a
disabled
key to true in the item. Such item will be rendered in gray and won't be clickable. -
When using the
single
prop,selectedItems
should still be passed in as an array of selected items keys. Also, when an item is selected in the single mode, the selected item is returned as an array of string. -
The
items
props must be passed as an array of objects with a compulsoryname
key present in each object as the name key is used to display the items in the options component. -
filterMethod partial example: searchTerm = "University of New" will return "University of New York", "University of New Orleans", "The University of New York" as well as "University of Columbia" and "New England Tech" due to partial matches.
-
filterMethod full example: searchTerm = "University of New" will return" University of New York", "University of New Orleans", "The University of New York" because all three contain the substring "University of New"
To use, add ref to MultiSelect component in parent component, then call method against reference. i.e.
<MultiSelect
ref={c => this._multiSelect = c}
...
/>
clearSelectedCategories = () => {
this._multiSelect._removeAllItems();
};
Contributions are welcome and will be fully credited.
Contributions are accepted via Pull Requests on Github.
-
Document any change in behaviour - Make sure the
README.md
and any other relevant documentation are kept up-to-date. -
Consider our release cycle - We try to follow SemVer v2.0.0. Randomly breaking public APIs is not an option.
-
Create feature branches - Don't ask us to pull from your master branch.
-
One pull request per feature - If you want to do more than one thing, send multiple pull requests.
-
Send coherent history - Make sure each individual commit in your pull request is meaningful. If you had to make multiple intermediate commits while developing, please squash them before submitting.
Check issues for current issues.
Here is list of CONTRIBUTORS
The MIT License (MIT). Please see LICENSE for more information.