R: ChosenJS React Multi Select
HTML
<div class="js-app"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<script src="https://npmcdn.com/classnames/index.js"></script>
<script src="https://npmcdn.com/react-input-autosize/dist/react-input-autosize.js"></script>
<script src="https://npmcdn.com/react-select/dist/react-select.js"></script>
CSS
/**
* React Select
* ============
* Created by Jed Watson and Joss Mackison for KeystoneJS, http://www.keystonejs.com/
* https://twitter.com/jedwatson https://twitter.com/jossmackison https://twitter.com/keystonejs
* MIT License: https://github.com/JedWatson/react-select
*/
.Select {
position: relative;
}
.Select,
.Select div,
.Select input,
.Select span {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.Select.is-disabled > .Select-control {
background-color: #f9f9f9;
}
.Select.is-disabled > .Select-control:hover {
box-shadow: none;
}
.Select.is-disabled .Select-arrow-zone {
cursor: default;
pointer-events: none;
}
.Select-control {
background-color: #fff;
border-color: #d9d9d9 #ccc #b3b3b3;
border-radius: 4px;
border: 1px solid #ccc;
color: #333;
cursor: default;
display: table;
border-spacing: 0;
border-collapse: separate;
height: 36px;
outline: none;
overflow: hidden;
position: relative;
width: 100%;
}
.Select-control:hover {
box-shadow: 0 1px 0 rgba(0, 0, 0, 0.06);
}
.Select-control .Select-input:focus {
outline: none;
}
.is-searchable.is-open > .Select-control {
cursor: text;
}
.is-open > .Select-control {
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
background: #fff;
border-color: #b3b3b3 #ccc #d9d9d9;
}
.is-open > .Select-control > .Select-arrow {
border-color: transparent transparent #999;
border-width: 0 5px 5px;
}
.is-searchable.is-focused:not(.is-open) > .Select-control {
cursor: text;
}
.is-focused:not(.is-open) > .Select-control {
border-color: #007eff;
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 0 3px rgba(0, 126, 255, 0.1);
}
.Select-placeholder,
.Select--single > .Select-control .Select-value {
bottom: 0;
color: #aaa;
left: 0;
line-height: 34px;
padding-left: 10px;
padding-right: 10px;
position: absolute;
right: 0;
top: 0;
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
...
Babel + JSX
console.clear();
var orderData = [
{
id: 1,
status: 'working'
},
{
id: 2,
status: 'pending'
},
{
id: 3,
status: 'rejected'
},
{
id: 4,
status: 'complete'
}
];
let options = [
{ value: 'working', label: 'Working' },
{ value: 'pending', label: 'Pending' },
{ value: 'rejected', label: 'Rejected' },
{ value: 'complete', label: 'Complete' }
];
let filters = options.map(function(option) {
return option.value;
});
var FilterableOrdersComponent = React.createClass({
getInitialState() {
return {
orders: this.props.orders
}
},
_onFilterSelected(filters) {
var filtersArray = filters == null || filters == '' ? this.props.filters : filters.split(','),
filteredOrders = this.props.orders.filter((index, element) => filtersArray.indexOf(index.status) != -1);
this.setState({
orders: filteredOrders
});
},
render() {
return (
<div>
<FilteredSearchComponent
filters={filters}
onFilterSelected={this._onFilterSelected}
/>
<OrdersComponent
orders={this.state.orders}
/>
</div>
)
}
});
var OrdersComponent = React.createClass({
render() {
const orders = this.props.orders.map((order) => <OrderComponent key={order.id} order={order} />);
return (
<div class="orders">{orders}</div>
);
}
});
var OrderComponent = React.createClass({
render() {
return (
<p>Status: {this.props.order.status}</p>
)
}
});
var FilteredSearchComponent = React.createClass({
getInitialState() {
return {
data: {
"option1": {
name: "option1",
fields: some text
},
"option2": {
name: "option2",
fields: [{some obj}]
},
"option3": {
name: "option3",
fields: some text,
...