diff --git a/src/Select.js b/src/Select.js index 9c22206e7c..cdf8d0ea2c 100644 --- a/src/Select.js +++ b/src/Select.js @@ -395,13 +395,12 @@ const Select = React.createClass({ this.setState({ isOpen: false, isPseudoFocused: this.state.isFocused && !this.props.multi, - inputValue: '' + inputValue: this.handleInputValueChange('') }); } else { this.setState({ isOpen: false, - isPseudoFocused: this.state.isFocused && !this.props.multi, - inputValue: this.state.inputValue + isPseudoFocused: this.state.isFocused && !this.props.multi }); } this.hasScrolledToOption = false; @@ -436,7 +435,7 @@ const Select = React.createClass({ isPseudoFocused: false, }; if (this.props.onBlurResetsInput) { - onBlurredState.inputValue = ''; + onBlurredState.inputValue = this.handleInputValueChange(''); } this.setState(onBlurredState); }, @@ -444,12 +443,8 @@ const Select = React.createClass({ handleInputChange (event) { let newInputValue = event.target.value; - if (this.state.inputValue !== event.target.value && this.props.onInputChange) { - let nextState = this.props.onInputChange(newInputValue); - // Note: != used deliberately here to catch undefined and null - if (nextState != null && typeof nextState !== 'object') { - newInputValue = '' + nextState; - } + if (this.state.inputValue !== event.target.value) { + newInputValue = this.handleInputValueChange(newInputValue); } this.setState({ @@ -459,6 +454,17 @@ const Select = React.createClass({ }); }, + handleInputValueChange(newValue) { + if (this.props.onInputChange) { + let nextState = this.props.onInputChange(newValue); + // Note: != used deliberately here to catch undefined and null + if (nextState != null && typeof nextState !== 'object') { + newValue = '' + nextState; + } + } + return newValue; + }, + handleKeyDown (event) { if (this.props.disabled) return; @@ -603,7 +609,7 @@ const Select = React.createClass({ this.hasScrolledToOption = false; if (this.props.multi) { this.setState({ - inputValue: '', + inputValue: this.handleInputValueChange(''), focusedIndex: null }, () => { this.addValue(value); @@ -611,7 +617,7 @@ const Select = React.createClass({ } else { this.setState({ isOpen: false, - inputValue: '', + inputValue: this.handleInputValueChange(''), isPseudoFocused: this.state.isFocused, }, () => { this.setValue(value); @@ -648,7 +654,7 @@ const Select = React.createClass({ this.setValue(this.getResetValue()); this.setState({ isOpen: false, - inputValue: '', + inputValue: this.handleInputValueChange(''), }, this.focus); }, diff --git a/test/Creatable-test.js b/test/Creatable-test.js index 968478fd9a..085993dcfb 100644 --- a/test/Creatable-test.js +++ b/test/Creatable-test.js @@ -19,7 +19,7 @@ var TestUtils = require('react-addons-test-utils'); var Select = require('../src/Select'); describe('Creatable', () => { - let creatableInstance, creatableNode, filterInputNode, innserSelectInstance, renderer; + let creatableInstance, creatableNode, filterInputNode, innerSelectInstance, renderer; beforeEach(() => renderer = TestUtils.createRenderer()); @@ -36,7 +36,7 @@ describe('Creatable', () => { ); creatableNode = ReactDOM.findDOMNode(creatableInstance); - innserSelectInstance = creatableInstance.select; + innerSelectInstance = creatableInstance.select; findAndFocusInputControl(); }; @@ -106,7 +106,7 @@ describe('Creatable', () => { createControl({ filterOptions: () => null }); - typeSearchText('test');; + typeSearchText('test'); }); it('should not show a "create..." prompt if current filter text is not a valid option (as determined by :isValidNewOption prop)', () => { @@ -158,6 +158,34 @@ describe('Creatable', () => { expect(options, 'to have length', 1); }); + it('should remove the new option after closing on selecting option', () => { + createControl({ + shouldKeyDownEventCreateNewOption: ({ keyCode }) => keyCode === 13 + }); + typeSearchText('9'); + TestUtils.Simulate.keyDown(filterInputNode, { keyCode: 40, key: 'ArrowDown' }); + TestUtils.Simulate.keyDown(filterInputNode, { keyCode: 13 }); + expect(creatableInstance.inputValue, 'to equal', ''); + }); + + it('should remove the new option after closing on escape', () => { + createControl({ + shouldKeyDownEventCreateNewOption: ({ keyCode }) => keyCode === 13 + }); + typeSearchText('9'); + TestUtils.Simulate.keyDown(filterInputNode, { keyCode: 27 }); + expect(creatableInstance.inputValue, 'to equal', ''); + }); + + it('should remove the new option after closing on blur', () => { + createControl({ + shouldKeyDownEventCreateNewOption: ({ keyCode }) => keyCode === 13 + }); + typeSearchText('9'); + TestUtils.Simulate.blur(filterInputNode); + expect(creatableInstance.inputValue, 'to equal', ''); + }); + it('should allow a custom select type to be rendered via the :children property', () => { let childProps; createControl({