From 3461a1fba3cac0cfbb96e694b7c1fae4640ec7cf Mon Sep 17 00:00:00 2001 From: Che' Jansen Date: Thu, 28 Jul 2016 12:53:09 +1000 Subject: [PATCH] Add create option to autocomplete --- components/autocomplete/Autocomplete.js | 6 +++++- components/autocomplete/readme.md | 1 + lib/autocomplete/Autocomplete.js | 10 ++++++++-- spec/components/autocomplete.js | 24 +++++++++++++++--------- 4 files changed, 29 insertions(+), 12 deletions(-) diff --git a/components/autocomplete/Autocomplete.js b/components/autocomplete/Autocomplete.js index bd76bab3..bd46a842 100644 --- a/components/autocomplete/Autocomplete.js +++ b/components/autocomplete/Autocomplete.js @@ -27,6 +27,7 @@ const factory = (Chip, Input) => { showSuggestionsWhenValueIsSet: PropTypes.bool, source: PropTypes.any, suggestionMatch: PropTypes.oneOf(['start', 'anywhere', 'word']), + create: PropTypes.bool, theme: PropTypes.shape({ active: PropTypes.string, autocomplete: PropTypes.string, @@ -117,6 +118,9 @@ const factory = (Chip, Input) => { let target = this.state.active; if (!target) { target = [...this.suggestions().keys()][0]; + if (this.props.create && !target){ + target = this.state.query; + } this.setState({active: target}); } this.select(target, event); @@ -272,7 +276,7 @@ const factory = (Chip, Input) => { const { error, label, source, suggestionMatch, //eslint-disable-line no-unused-vars selectedPosition, showSuggestionsWhenValueIsSet, //eslint-disable-line no-unused-vars - theme, ...other + theme, create, ...other } = this.props; const className = classnames(theme.autocomplete, { [theme.focus]: this.state.focus diff --git a/components/autocomplete/readme.md b/components/autocomplete/readme.md index 56bafa04..57251c2f 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 | `showSuggestionsWhenValueIsSet` | `Bool` | `false` | If true, the list of suggestions will not be filtered when a value is selected, until the query is modified. | | `suggestionMatch` | `String` | `start` | Determines how suggestions are supplied. It can be `start` (query matches the start of a suggestion), `anywhere` (query matches anywhere inside the suggestion), or `word` (query matches the start of a word in the suggestion). | | `value` | `String` or `Array` | | Value or array of values currently selected component.| +| `create` | `Bool` | `false` | Determines if user can create a new option by typing in the field Additional properties will be passed to the Input Component so you can use `hint`, `name` ... etc. diff --git a/lib/autocomplete/Autocomplete.js b/lib/autocomplete/Autocomplete.js index b97c69bf..3f0d3513 100644 --- a/lib/autocomplete/Autocomplete.js +++ b/lib/autocomplete/Autocomplete.js @@ -104,6 +104,9 @@ var factory = function factory(Chip, Input) { var target = _this.state.active; if (!target) { target = [].concat(_toConsumableArray(_this.suggestions().keys()))[0]; + if (_this.props.create && !target) { + target = _this.state.query; + } _this.setState({ active: target }); } _this.select(target, event); @@ -158,7 +161,8 @@ var factory = function factory(Chip, Input) { }, { key: 'query', value: function query(key) { - return !this.props.multiple && key ? this.source().get(key) : ''; + var value = this.props.create && !this.source().get(key) ? key : this.source().get(key); + return !this.props.multiple && key ? value : ''; } }, { key: 'suggestions', @@ -397,8 +401,9 @@ var factory = function factory(Chip, Input) { var selectedPosition = _props.selectedPosition; var showSuggestionsWhenValueIsSet = _props.showSuggestionsWhenValueIsSet; var theme = _props.theme; + var create = _props.create; - var other = _objectWithoutProperties(_props, ['error', 'label', 'source', 'suggestionMatch', 'selectedPosition', 'showSuggestionsWhenValueIsSet', 'theme']); + var other = _objectWithoutProperties(_props, ['error', 'label', 'source', 'suggestionMatch', 'selectedPosition', 'showSuggestionsWhenValueIsSet', 'theme', 'create']); var className = (0, _classnames5.default)(theme.autocomplete, _defineProperty({}, theme.focus, this.state.focus), this.props.className); @@ -439,6 +444,7 @@ var factory = function factory(Chip, Input) { showSuggestionsWhenValueIsSet: _react.PropTypes.bool, source: _react.PropTypes.any, suggestionMatch: _react.PropTypes.oneOf(['start', 'anywhere', 'word']), + create: _react.PropTypes.bool, theme: _react.PropTypes.shape({ active: _react.PropTypes.string, autocomplete: _react.PropTypes.string, diff --git a/spec/components/autocomplete.js b/spec/components/autocomplete.js index ad0de47d..9ed6f10d 100644 --- a/spec/components/autocomplete.js +++ b/spec/components/autocomplete.js @@ -1,19 +1,24 @@ import React from 'react'; import Autocomplete from '../../components/autocomplete'; -const countriesArray = ['Spain', 'England', 'USA', 'Thailand', 'Tongo', 'Slovenia']; -const countriesObject = {'ES-es': 'Spain', 'TH-th': 'Thailand', 'EN-gb': 'England', - 'EN-en': 'United States of America', 'EN-nz': 'New Zealand'}; - class AutocompleteTest extends React.Component { state = { simple: 'Spain', simpleShowAll: 'England', - multiple: ['ES-es', 'TH-th'] + multiple: ['ES-es', 'TH-th'], + countriesArray: ['Spain', 'England', 'USA', 'Thailand', 'Tongo', 'Slovenia'], + countriesObject: {'ES-es': 'Spain', 'TH-th': 'Thailand', 'EN-gb': 'England', + 'EN-en': 'United States of America', 'EN-nz': 'New Zealand'} }; handleMultipleChange = (value) => { - this.setState({multiple: value}); + this.setState({ + multiple: value, + countriesObject: { + ...this.state.countriesObject, + ...!this.state.countriesObject[value[0]] ? {[value[0]]: value[0]} : {} + } + }); }; handleSimpleChange = (value) => { @@ -33,9 +38,10 @@ class AutocompleteTest extends React.Component { @@ -52,7 +58,7 @@ class AutocompleteTest extends React.Component { hint="Elements up to you..." multiple={false} onChange={this.handleSimpleShowAllChange} - source={countriesArray} + source={this.state.countriesArray} value={this.state.simpleShowAll} showSuggestionsWhenValueIsSet />