Enable dynamic source for single value Autocomplete (#1120)

old
Václav Chalupa 2017-01-18 08:34:27 +01:00 committed by Javi Velasco
parent d3fe9f9868
commit d80dc82991
3 changed files with 53 additions and 13 deletions

View File

@ -34,6 +34,7 @@ const factory = (Chip, Input) => {
onChange: PropTypes.func,
onFocus: PropTypes.func,
onQueryChange: PropTypes.func,
query: PropTypes.string,
selectedPosition: PropTypes.oneOf(['above', 'below', 'none']),
showSelectedWhenNotInSource: PropTypes.bool,
showSuggestionsWhenValueIsSet: PropTypes.bool,
@ -70,15 +71,14 @@ const factory = (Chip, Input) => {
direction: this.props.direction,
focus: false,
showAllSuggestions: this.props.showSuggestionsWhenValueIsSet,
query: this.query(this.props.value),
query: this.props.query ? this.props.query : this.query(this.props.value),
isValueAnObject: false
};
componentWillReceiveProps (nextProps) {
if (!this.props.multiple) {
this.setState({
query: this.query(nextProps.value)
});
const query = nextProps.query ? nextProps.query : this.query(nextProps.value);
this.updateQuery(query, false);
}
}
@ -104,6 +104,7 @@ const factory = (Chip, Input) => {
ReactDOM.findDOMNode(this).querySelector('input').blur();
});
}
this.updateQuery(query, this.props.query);
};
handleMouseDown = (event) => {
@ -115,9 +116,17 @@ const factory = (Chip, Input) => {
if (this.props.onBlur) this.props.onBlur(event, this.state.active);
};
updateQuery = (query, notify) => {
if (notify && this.props.onQueryChange) this.props.onQueryChange(query);
this.setState({ query });
}
handleQueryChange = (value) => {
if (this.props.onQueryChange) this.props.onQueryChange(value);
this.setState({query: value, showAllSuggestions: false, active: null});
const query = this.clearQuery ? '' : value;
this.clearQuery = false;
this.updateQuery(query, true);
this.setState({showAllSuggestions: false, active: null});
};
handleQueryFocus = (event) => {
@ -127,15 +136,12 @@ const factory = (Chip, Input) => {
};
handleQueryKeyDown = (event) => {
// Clear query when pressing backspace and showing all suggestions.
const shouldClearQuery = (
// Mark query for clearing in handleQueryChange when pressing backspace and showing all suggestions.
this.clearQuery = (
event.which === 8
&& this.props.showSuggestionsWhenValueIsSet
&& this.state.showAllSuggestions
);
if (shouldClearQuery) {
this.setState({query: ''});
}
if (event.which === 13) {
this.selectOrCreateActiveItem(event);
@ -374,7 +380,7 @@ const factory = (Chip, Input) => {
render () {
const {
allowCreate, error, label, source, suggestionMatch, //eslint-disable-line no-unused-vars
allowCreate, error, label, source, suggestionMatch, query, //eslint-disable-line no-unused-vars
selectedPosition, keepFocusOnChange, showSuggestionsWhenValueIsSet, showSelectedWhenNotInSource, onQueryChange, //eslint-disable-line no-unused-vars
theme, ...other
} = this.props;

View File

@ -55,6 +55,7 @@ If you want to provide a theme via context, the component key is `RTAutocomplete
| `onChange` | `Function` | | Callback function that is fired when the components's value changes. |
| `onQueryChange` | `Function` | | Callback function that is fired when the components's query input value changes. |
| `onFocus` | `Function` | | Callback function that is fired when component is focused. |
| `query` | `String` | | This property has to be used in case the `source` is not static and will be changing during search for `multiple={false}` autocomplete, content of the `query` has to be managed by the `onQueryChange` callback. |
| `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`, `below` or `none`. |
| `showSelectedWhenNotInSource` | `Bool` | `false` | Determines if the selected list is shown if the `value` keys don't exist in the source. Only works if passing the `value` prop as an Object. |

View File

@ -4,17 +4,37 @@ const countriesObject = {'ES-es': 'Spain', 'TH-th': 'Thailand', 'EN-gb': 'Englan
class AutocompleteTest extends React.Component {
state = {
simple: 'Spain',
multiple: ['ES-es', 'TH-th']
multiple: ['ES-es', 'TH-th'],
dynamicSimple: '',
dynamicSource: {},
query: ''
};
handleSimpleChange = (value) => {
this.setState({simple: value});
};
handleDynamicSimpleChange = (value) => {
this.setState({dynamicSimple: value});
};
handleMultipleChange = (value) => {
this.setState({multiple: value});
};
handleQueryChange = (value) => {
this.setState({query: value});
};
generateSource = (event) => {
const query = event.target.value;
const source = {
A: query + ' # A',
B: query + ' # B'
};
this.setState({dynamicSource: source});
}
render () {
return (
<div>
@ -35,6 +55,19 @@ class AutocompleteTest extends React.Component {
source={countriesArray}
value={this.state.simple}
/>
<Autocomplete
direction="down"
label="Type to load new source"
hint="You can only choose one..."
multiple={false}
onChange={this.handleDynamicSimpleChange}
onInput={this.generateSource}
onQueryChange={this.handleQueryChange}
query={this.state.query}
source={this.state.dynamicSource}
value={this.state.dynamicSimple}
/>
</div>
);
}