Merge pull request #484 from lucaas/fix-483-autocomplete-unintuitive-filter-behaviour-with-multiple-false
Fix #483: Autocomplete unintuitive filter behavior with multiple=falseold
commit
563868b90e
|
@ -22,6 +22,7 @@ class Autocomplete extends React.Component {
|
|||
multiple: React.PropTypes.bool,
|
||||
onChange: React.PropTypes.func,
|
||||
selectedPosition: React.PropTypes.oneOf(['above', 'below']),
|
||||
showSuggestionsWhenValueIsSet: React.PropTypes.bool,
|
||||
source: React.PropTypes.any,
|
||||
value: React.PropTypes.any
|
||||
};
|
||||
|
@ -31,12 +32,14 @@ class Autocomplete extends React.Component {
|
|||
direction: 'auto',
|
||||
selectedPosition: 'above',
|
||||
multiple: true,
|
||||
showSuggestionsWhenValueIsSet: false,
|
||||
source: {}
|
||||
};
|
||||
|
||||
state = {
|
||||
direction: this.props.direction,
|
||||
focus: false,
|
||||
showAllSuggestions: this.props.showSuggestionsWhenValueIsSet,
|
||||
query: this.query(this.props.value)
|
||||
};
|
||||
|
||||
|
@ -61,7 +64,10 @@ class Autocomplete extends React.Component {
|
|||
const key = this.props.multiple ? keys : keys[0];
|
||||
const query = this.query(key);
|
||||
if (this.props.onChange) this.props.onChange(key, event);
|
||||
this.setState({ focus: false, query }, () => { this.refs.input.blur(); });
|
||||
this.setState(
|
||||
{focus: false, query, showAllSuggestions: this.props.showSuggestionsWhenValueIsSet},
|
||||
() => { this.refs.input.blur(); }
|
||||
);
|
||||
};
|
||||
|
||||
handleQueryBlur = () => {
|
||||
|
@ -69,7 +75,7 @@ class Autocomplete extends React.Component {
|
|||
};
|
||||
|
||||
handleQueryChange = (value) => {
|
||||
this.setState({query: value});
|
||||
this.setState({query: value, showAllSuggestions: false});
|
||||
};
|
||||
|
||||
handleQueryFocus = () => {
|
||||
|
@ -77,6 +83,18 @@ class Autocomplete extends React.Component {
|
|||
this.setState({active: '', focus: true});
|
||||
};
|
||||
|
||||
handleQueryKeyDown = (event) => {
|
||||
// Clear query when pressing backspace and showing all suggestions.
|
||||
const shouldClearQuery = (
|
||||
event.which === 8
|
||||
&& this.props.showSuggestionsWhenValueIsSet
|
||||
&& this.state.showAllSuggestions
|
||||
);
|
||||
if (shouldClearQuery) {
|
||||
this.setState({query: ''});
|
||||
}
|
||||
};
|
||||
|
||||
handleQueryKeyUp = (event) => {
|
||||
if (event.which === 13 && this.state.active) this.select(this.state.active, event);
|
||||
if (event.which === 27) this.refs.input.blur();
|
||||
|
@ -109,15 +127,32 @@ class Autocomplete extends React.Component {
|
|||
}
|
||||
|
||||
suggestions () {
|
||||
const suggest = new Map();
|
||||
let suggest = new Map();
|
||||
const query = this.state.query.toLowerCase().trim() || '';
|
||||
const values = this.values();
|
||||
for (const [key, value] of this.source()) {
|
||||
if (value.toLowerCase().trim().startsWith(query)
|
||||
&& (!values.has(key) || !this.props.multiple)) {
|
||||
suggest.set(key, value);
|
||||
const source = this.source();
|
||||
|
||||
// Suggest any non-set value which matches the query
|
||||
if (this.props.multiple) {
|
||||
for (const [key, value] of source) {
|
||||
if (!values.has(key) && value.toLowerCase().trim().startsWith(query)) {
|
||||
suggest.set(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
// When multiple is false, suggest any value which matches the query if showAllSuggestions is false
|
||||
} else if (query && !this.state.showAllSuggestions) {
|
||||
for (const [key, value] of source) {
|
||||
if (value.toLowerCase().trim().startsWith(query)) {
|
||||
suggest.set(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
// When multiple is false, suggest all values when showAllSuggestions is true
|
||||
} else {
|
||||
suggest = source;
|
||||
}
|
||||
|
||||
return suggest;
|
||||
}
|
||||
|
||||
|
@ -209,6 +244,7 @@ class Autocomplete extends React.Component {
|
|||
onBlur={this.handleQueryBlur}
|
||||
onChange={this.handleQueryChange}
|
||||
onFocus={this.handleQueryFocus}
|
||||
onKeyDown={this.handleQueryKeyDown}
|
||||
onKeyUp={this.handleQueryKeyUp}
|
||||
value={this.state.query}
|
||||
/>
|
||||
|
|
|
@ -50,6 +50,7 @@ class AutocompleteTest extends React.Component {
|
|||
| `onChange` | `Function` | | Callback function that is fired when the components's value changes.|
|
||||
| `source` | `Object` or `Array` | | Object of key/values or array representing all items suggested. |
|
||||
| `selectedPosition` | `String` | `above` | Determines if the selected list is shown above or below input. It can be `above` or `below`. |
|
||||
| `showSuggestionsWhenValueIsSet` | `Bool` | `false` | If true, the list of suggestions will not be filtered when a value is selected, until the query is modified. |
|
||||
| `value` | `String` or `Array` | | Value or array of values currently selected component.|
|
||||
|
||||
Additional properties will be passed to the Input Component so you can use `hint`, `name` ... etc.
|
||||
|
|
|
@ -189,6 +189,11 @@ declare namespace __RT {
|
|||
* Object of key/values or array representing all items suggested.
|
||||
*/
|
||||
source: Object | Array<any>,
|
||||
/**
|
||||
* If true, the list of suggestions will not be filtered when a value is selected, until the query is modified.
|
||||
* @default false
|
||||
*/
|
||||
showSuggestionsWhenValueIsSet?: boolean,
|
||||
/**
|
||||
* Type of the input element. It can be a valid HTML5 input type
|
||||
* @default text
|
||||
|
|
|
@ -7,6 +7,7 @@ const countriesObject = {'ES-es': 'Spain', 'TH-th': 'Thailand', 'EN-gb': 'Englan
|
|||
class AutocompleteTest extends React.Component {
|
||||
state = {
|
||||
simple: 'Spain',
|
||||
simpleShowAll: 'England',
|
||||
multiple: ['ES-es', 'TH-th']
|
||||
};
|
||||
|
||||
|
@ -18,6 +19,10 @@ class AutocompleteTest extends React.Component {
|
|||
this.setState({simple: value});
|
||||
};
|
||||
|
||||
handleSimpleShowAllChange = (value) => {
|
||||
this.setState({simpleShowAll: value});
|
||||
};
|
||||
|
||||
render () {
|
||||
return (
|
||||
<section>
|
||||
|
@ -39,6 +44,16 @@ class AutocompleteTest extends React.Component {
|
|||
source={countriesArray}
|
||||
value={this.state.simple}
|
||||
/>
|
||||
|
||||
<Autocomplete
|
||||
label="Choose a country (showing all suggestions)"
|
||||
hint="Elements up to you..."
|
||||
multiple={false}
|
||||
onChange={this.handleSimpleShowAllChange}
|
||||
source={countriesArray}
|
||||
value={this.state.simpleShowAll}
|
||||
showSuggestionsWhenValueIsSet
|
||||
/>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue