diff --git a/components/autocomplete/Autocomplete.js b/components/autocomplete/Autocomplete.js index 44a2a1ff..32c6d647 100644 --- a/components/autocomplete/Autocomplete.js +++ b/components/autocomplete/Autocomplete.js @@ -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; diff --git a/components/autocomplete/readme.md b/components/autocomplete/readme.md index f33d7033..5da6b8ba 100644 --- a/components/autocomplete/readme.md +++ b/components/autocomplete/readme.md @@ -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. | diff --git a/docs/app/components/layout/main/modules/examples/autocomplete_example_1.txt b/docs/app/components/layout/main/modules/examples/autocomplete_example_1.txt index 41a96580..6260db11 100644 --- a/docs/app/components/layout/main/modules/examples/autocomplete_example_1.txt +++ b/docs/app/components/layout/main/modules/examples/autocomplete_example_1.txt @@ -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 (
@@ -35,6 +55,19 @@ class AutocompleteTest extends React.Component { source={countriesArray} value={this.state.simple} /> + +
); }