From 4ca6218769bbbe01c1f6c5d1ba1747517f656587 Mon Sep 17 00:00:00 2001 From: Asheesh Karwal Date: Thu, 27 Aug 2015 12:24:55 +1000 Subject: [PATCH 1/2] Add or clear current input value on blur and allow auto select on tab (for new values) - fixes #415 --- src/Select.js | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/Select.js b/src/Select.js index 7c4517e083..84bddbbca0 100644 --- a/src/Select.js +++ b/src/Select.js @@ -312,6 +312,19 @@ var Select = React.createClass({ this.setValue(this.state.values.concat(value)); }, + addOrClearInputValue: function() { + var inputValue = this.state.inputValue; + if((inputValue || '').length === 0) { + return; + } + if (this.props.allowCreate) { + this.setValue(this.state.values.concat(inputValue), false); + } + else { + this.setState({ inputValue: null }); + } + }, + popValue: function() { this.setValue(this.state.values.slice(0, this.state.values.length - 1)); }, @@ -412,6 +425,7 @@ var Select = React.createClass({ }, handleInputBlur: function(event) { + this.addOrClearInputValue(); this._blurTimeout = setTimeout(() => { if (this._focusAfterUpdate) return; this.setState({ @@ -433,7 +447,7 @@ var Select = React.createClass({ } return; case 9: // tab - if (event.shiftKey || !this.state.isOpen || !this.state.focusedOption) { + if (!this.state.isOpen) { return; } this.selectFocusedOption(); From 3fbd189dd9c92f27673e654db39979abc7484bf1 Mon Sep 17 00:00:00 2001 From: Asheesh Karwal Date: Fri, 28 Aug 2015 12:16:42 +1000 Subject: [PATCH 2/2] Does not show add option if entered value exists #421 --- src/Select.js | 9 ++++++++- test/Select-test.js | 10 +++++----- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/Select.js b/src/Select.js index 84bddbbca0..09838bd381 100644 --- a/src/Select.js +++ b/src/Select.js @@ -675,6 +675,13 @@ var Select = React.createClass({ } }, + inputValueExists : function() { + var matches = this.state.filteredOptions.filter(function(option) { + return String(option.value) === this.state.inputValue; + }, this); + return matches.length > 0; + }, + buildMenu: function() { var focusedValue = this.state.focusedOption ? this.state.focusedOption.value : null; var renderLabel = this.props.optionRenderer || function(op) { @@ -685,7 +692,7 @@ var Select = React.createClass({ } // Add the current value to the filtered options in last resort var options = this.state.filteredOptions; - if (this.props.allowCreate && this.state.inputValue.trim()) { + if (this.props.allowCreate && this.state.inputValue.trim() && !this.inputValueExists()) { var inputValue = this.state.inputValue; options = options.slice(); var newOption = this.props.newOptionCreator ? this.props.newOptionCreator(inputValue) : { diff --git a/test/Select-test.js b/test/Select-test.js index a070a122ac..1998e0dd9a 100644 --- a/test/Select-test.js +++ b/test/Select-test.js @@ -902,7 +902,7 @@ describe('Select', function() { pressEnterToAccept(); expect(onChange, 'was not called'); // And the menu is still open - expect(React.findDOMNode(instance), 'to contain no elements matching', DISPLAYED_SELECTION_SELECTOR) + expect(React.findDOMNode(instance), 'to contain no elements matching', DISPLAYED_SELECTION_SELECTOR); expect(React.findDOMNode(instance), 'queried for' , '.Select-option', 'to satisfy', [ expect.it('to have text', 'Two') @@ -915,7 +915,7 @@ describe('Select', function() { pressEnterToAccept(); expect(onChange, 'was not called'); // And the menu is still open - expect(React.findDOMNode(instance), 'to contain no elements matching', DISPLAYED_SELECTION_SELECTOR) + expect(React.findDOMNode(instance), 'to contain no elements matching', DISPLAYED_SELECTION_SELECTOR); expect(React.findDOMNode(instance), 'queried for' , '.Select-option', 'to satisfy', [ expect.it('to have text', 'Two') @@ -928,7 +928,7 @@ describe('Select', function() { pressEnterToAccept(); expect(onChange, 'was not called'); // And the menu is still open - expect(React.findDOMNode(instance), 'to contain no elements matching', DISPLAYED_SELECTION_SELECTOR) + expect(React.findDOMNode(instance), 'to contain no elements matching', DISPLAYED_SELECTION_SELECTOR); expect(React.findDOMNode(instance), 'queried for' , '.Select-option', 'to satisfy', [ expect.it('to have text', 'Two') @@ -1157,14 +1157,14 @@ describe('Select', function() { 'to have text', 'Add test to values?'); }); - it('does not display the option label when an existing value is entered', function () { + it('does not display add option when an existing value is entered', function () { typeSearchText('zzzzz'); expect(React.findDOMNode(instance).querySelectorAll('.Select-menu .Select-option'), 'to have length', 1); expect(React.findDOMNode(instance), 'queried for first', '.Select-menu .Select-option', - 'to have text', 'Add zzzzz to values?'); + 'to have text', 'test value'); }); it('renders the existing option and an add option when an existing display label is entered', function () {