react-filtered-multiselect
Advanced tools
Comparing version 0.1.1 to 0.2.0
@@ -0,1 +1,14 @@ | ||
## 0.2.0 - 2014-12-06 | ||
**Breaking:** If you want selected options to no longer appear in the select, | ||
you now _must_ either pass them back to `FilteredMultiSelect` via its | ||
`selectedOptions` prop or manually remove them from list that gets passed as its | ||
`options` prop. | ||
Fixed: `FilteredMultiSelect` will now re-render if its `options` prop is | ||
replaced with another object, or `options.length` changes. | ||
Removed React from package.json `dependencies` - it's now only in | ||
`peerDependencies`. | ||
## 0.1.1 - 2014-11-13 | ||
@@ -2,0 +15,0 @@ |
98
index.js
@@ -49,3 +49,3 @@ 'use strict'; | ||
getDefaultProps: function() { | ||
getDefaultProps:function() { | ||
return { | ||
@@ -69,11 +69,9 @@ buttonText: 'Select' | ||
getInitialState: function() { | ||
getInitialState:function() { | ||
var $__0= this.props,defaultFilter=$__0.defaultFilter,selectedOptions=$__0.selectedOptions | ||
return { | ||
// Filter text | ||
filter: this.props.defaultFilter | ||
filter: defaultFilter | ||
// Options which haven't been selected and match the filter text | ||
, filteredOptions: this.filterOptions(this.props.defaultFilter, | ||
this.props.selectedOptions) | ||
// Options which have been selected by pressing Enter or the Select button | ||
, selectedOptions: this.props.selectedOptions.slice() | ||
, filteredOptions: this._filterOptions(defaultFilter, selectedOptions) | ||
// Values of <options> currently selected in the <select> | ||
@@ -84,12 +82,19 @@ , selectedValues: [] | ||
componentWillReceiveProps: function(nextProps) { | ||
if (nextProps.selectedOptions.length != this.state.selectedOptions.length) { | ||
componentWillReceiveProps:function(nextProps) { | ||
// Update visibile options in response to options or selectedOptions | ||
// changing. Also update selected values after the re-render completes, as | ||
// one of the previously selected options may have been removed. | ||
if (nextProps.options !== this.props.options || | ||
nextProps.selectedOptions !== this.props.selectedOptions || | ||
nextProps.options.length != this.props.options.length || | ||
nextProps.selectedOptions.length != this.props.selectedOptions.length) { | ||
this.setState({ | ||
filteredOptions: this.filterOptions(this.state.filter, nextProps.selectedOptions) | ||
, selectedOptions: nextProps.selectedOptions.slice() | ||
}) | ||
filteredOptions: this._filterOptions(this.state.filter, | ||
nextProps.selectedOptions, | ||
nextProps.options) | ||
}, this._updateSelectedValues) | ||
} | ||
}, | ||
filterOptions: function(filter, selectedOptions) { | ||
_filterOptions:function(filter, selectedOptions, options) { | ||
if (typeof filter == 'undefined') { | ||
@@ -99,9 +104,10 @@ filter = this.state.filter | ||
if (typeof selectedOptions == 'undefined') { | ||
selectedOptions = this.state.selectedOptions | ||
selectedOptions = this.props.selectedOptions | ||
} | ||
if (typeof options == 'undefined') { | ||
options = this.props.options | ||
} | ||
filter = filter.toUpperCase() | ||
var options = this.props.options | ||
var textProp = this.props.textProp | ||
var valueProp = this.props.valueProp | ||
var $__0= this.props,textProp=$__0.textProp,valueProp=$__0.valueProp | ||
var selectedValueLookup = makeLookup(selectedOptions, valueProp) | ||
@@ -120,11 +126,11 @@ var filteredOptions = [] | ||
onFilterChange: function(e) { | ||
_onFilterChange:function(e) { | ||
var filter = e.target.value | ||
this.setState({ | ||
filter: filter | ||
, filteredOptions: this.filterOptions(filter) | ||
}) | ||
filter:filter | ||
, filteredOptions: this._filterOptions(filter) | ||
}, this._updateSelectedValues) | ||
}, | ||
onFilterKeyPress: function(e) { | ||
_onFilterKeyPress:function(e) { | ||
if (e.key == 'Enter') { | ||
@@ -134,8 +140,6 @@ e.preventDefault() | ||
var selectedOption = this.state.filteredOptions[0] | ||
var selectedOptions = this.state.selectedOptions.slice().concat([selectedOption]) | ||
this.setState({ | ||
filter: '' | ||
, filteredOptions: this.filterOptions('', selectedOptions) | ||
, selectedOptions: selectedOptions | ||
}, this.props.onChange.bind(null, selectedOptions)) | ||
var selectedOptions = this.props.selectedOptions.concat([selectedOption]) | ||
this.setState({filter: '', selectedValues: []}, function() { | ||
this.props.onChange(selectedOptions) | ||
}.bind(this)) | ||
} | ||
@@ -145,4 +149,4 @@ } | ||
onSelectChange: function(e) { | ||
var el = e.target | ||
_updateSelectedValues:function(e) { | ||
var el = e ? e.target : this.refs.select.getDOMNode() | ||
var selectedValues = [] | ||
@@ -154,20 +158,21 @@ for (var i = 0, l = el.options.length; i < l; i++) { | ||
} | ||
this.setState({selectedValues: selectedValues}) | ||
// Always update if we were handling an event, otherwise only update if | ||
// selectedValues has actually changed. | ||
if (e || String(this.state.selectedValues) != String(selectedValues)) { | ||
this.setState({selectedValues:selectedValues}) | ||
} | ||
}, | ||
selectOptions: function(e) { | ||
_onButtonClick:function(e) { | ||
var selectedOptions = | ||
this.state.selectedOptions.concat(getItemsByProp(this.state.filteredOptions, | ||
this.props.selectedOptions.concat(getItemsByProp(this.state.filteredOptions, | ||
this.props.valueProp, | ||
this.state.selectedValues)) | ||
this.setState({ | ||
filteredOptions: this.filterOptions(this.state.filter, selectedOptions) | ||
, selectedOptions: selectedOptions | ||
, selectedValues: [] | ||
}, this.props.onChange.bind(null, selectedOptions)) | ||
this.setState({selectedValues: []}, function() { | ||
this.props.onChange(selectedOptions) | ||
}.bind(this)) | ||
}, | ||
render: function() { | ||
var props = this.props | ||
var state = this.state | ||
render:function() { | ||
var $__0= this,props=$__0.props,state=$__0.state | ||
return React.createElement("div", {className: props.className}, | ||
@@ -179,13 +184,14 @@ React.createElement("input", { | ||
value: state.filter, | ||
onChange: this.onFilterChange, | ||
onKeyPress: this.onFilterKeyPress, | ||
onChange: this._onFilterChange, | ||
onKeyPress: this._onFilterKeyPress, | ||
disabled: props.disabled} | ||
), | ||
React.createElement("select", {multiple: true, | ||
ref: "select", | ||
className: props.classNames.select, | ||
size: props.size, | ||
value: state.selectedValues, | ||
onChange: this.onSelectChange, | ||
onChange: this._updateSelectedValues, | ||
disabled: props.disabled}, | ||
this.state.filteredOptions.map(function(option) { | ||
this.state.filteredOptions.map(function(option) { | ||
return React.createElement("option", {key: option[props.valueProp], value: option[props.valueProp]}, option[props.textProp]) | ||
@@ -197,3 +203,3 @@ }) | ||
disabled: state.selectedValues.length === 0, | ||
onClick: this.selectOptions}, | ||
onClick: this._onButtonClick}, | ||
this.props.buttonText | ||
@@ -200,0 +206,0 @@ ) |
{ | ||
"name": "react-filtered-multiselect", | ||
"description": "Filtered multi-select React component", | ||
"version": "0.1.1", | ||
"version": "0.2.0", | ||
"author": "Jonny Buchanan <jonathan.buchanan@gmail.com> (https://github.com/insin)", | ||
@@ -19,3 +19,2 @@ "keywords": [ | ||
"dependencies": { | ||
"react": ">=0.12.0" | ||
}, | ||
@@ -22,0 +21,0 @@ "devDependencies": { |
@@ -10,3 +10,3 @@ ## react-filtered-multiselect | ||
### About | ||
### Features | ||
@@ -29,2 +29,6 @@ This component manages an `<input>`, a `<select multiple>` and a `<button>`. | ||
To hide already-selected items, pass them back to `FilteredMultiSelect` as its | ||
`selectedOptions` prop. This can be more convenient than manually removing the | ||
selected items from the list passed as `options`. | ||
To deselect items, remove them from the list passed back via the `onChange` | ||
@@ -55,3 +59,3 @@ callback and re-render the `FilteredMultiSelect` with the new list passed as its | ||
*v0.1.0* | ||
*v0.2.0* | ||
* [react-filtered-multiselect.js](https://github.com/insin/react-filtered-multiselect/raw/master/dist/react-filtered-multiselect.js) (development version) | ||
@@ -80,2 +84,8 @@ * [react-filtered-multiselect.min.js](https://github.com/insin/react-filtered-multiselect/raw/master/dist/react-filtered-multiselect.min.js) (compressed production version) | ||
The component will update its display if its `options` list changes length or | ||
is replaced with a different list, but it will *not* be able to detect changes | ||
which don't affect length or object equality, such as replacement of one option | ||
with another. Consider using `React.addons.update()` or other immutability | ||
helpers if you need to do this. | ||
`onChange(selectedOptions)` - callback which will be called with selected option | ||
@@ -98,3 +108,3 @@ objects each time the selection is added to. | ||
`selectedOptions` - array of option objects which are selected, so should no | ||
`selectedOptions` - list of option objects which are selected, so should no | ||
longer be displayed in the `<select>`. | ||
@@ -149,7 +159,7 @@ | ||
onMultiSelectChanged: function(selectedShips) { | ||
this.setState({selectedShips: selectedShips.slice()}) | ||
_onSelectionChange: function(selectedShips) { | ||
this.setState({selectedShips: selectedShips)}) | ||
}, | ||
deselectShip: function(index) { | ||
_onDeselect: function(index) { | ||
var selectedShips = this.state.selectedShips.slice() | ||
@@ -163,3 +173,3 @@ selectedShips.splice(index, 1) | ||
<FilteredMultiSelect | ||
onChange={this.onMultiSelectChanged} | ||
onChange={this._onSelectionChange} | ||
options={CULTURE_SHIPS} | ||
@@ -173,4 +183,4 @@ selectedOptions={this.state.selectedShips} | ||
{this.state.selectedShips.map(function(ship, i) { | ||
return <li>{ship.name}{' '} | ||
<button type="button" onClick={this.deselectShip.bind(null, i)}> | ||
return <li key={ship.id}>{ship.name}{' '} | ||
<button type="button" onClick={this._onDeselect.bind(null, i)}> | ||
× | ||
@@ -177,0 +187,0 @@ </button> |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
14996
1
183
188
- Removedreact@>=0.12.0