Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,7 @@ function onInputKeyDown(event) {
| `onNewOptionClick` | function | new option click handler, it calls when new option has been selected. `function(option) {}` |
| `shouldKeyDownEventCreateNewOption` | function | Decides if a keyDown event (eg its `keyCode`) should result in the creation of a new option. ENTER, TAB and comma keys create new options by default. Expected signature: `({ keyCode: number }): boolean` |
| `promptTextCreator` | function | Factory for overriding default option creator prompt label. By default it will read 'Create option "{label}"'. Expected signature: `(label: String): String` |
| `showNewOptionAtTop` | boolean | `true`: (Default) Show new option at top of list <br> `false`: Show new option at bottom of list |

### Methods

Expand Down
24 changes: 23 additions & 1 deletion examples/src/components/Creatable.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ var CreatableDemo = createClass({
},
getInitialState () {
return {
atTop: true,
multi: true,
multiValue: [],
options: [
Expand All @@ -30,7 +31,7 @@ var CreatableDemo = createClass({
}
},
render () {
const { multi, multiValue, options, value } = this.state;
const { atTop, multi, multiValue, options, value } = this.state;
return (
<div className="section">
<h3 className="section-heading">{this.props.label} <a href="https://github.com/JedWatson/react-select/tree/master/examples/src/components/Creatable.js">(Source)</a></h3>
Expand All @@ -39,6 +40,7 @@ var CreatableDemo = createClass({
options={options}
onChange={this.handleOnChange}
value={multi ? multiValue : value}
showNewOptionAtTop={atTop}
/>
<div className="hint">{this.props.hint}</div>
<div className="checkbox-list">
Expand All @@ -61,6 +63,26 @@ var CreatableDemo = createClass({
<span className="checkbox-label">Single Value</span>
</label>
</div>
<div className="checkbox-list">
<label className="checkbox">
<input
type="radio"
className="checkbox-control"
checked={atTop}
onChange={() => this.setState({ atTop: true })}
/>
<span className="checkbox-label">New option at top</span>
</label>
<label className="checkbox">
<input
type="radio"
className="checkbox-control"
checked={!atTop}
onChange={() => this.setState({ atTop: false })}
/>
<span className="checkbox-label">New option at bottom</span>
</label>
</div>
</div>
);
}
Expand Down
16 changes: 13 additions & 3 deletions src/Creatable.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class CreatableSelect extends React.Component {
}

filterOptions (...params) {
const { filterOptions, isValidNewOption, promptTextCreator } = this.props;
const { filterOptions, isValidNewOption, promptTextCreator, showNewOptionAtTop } = this.props;

// TRICKY Check currently selected options as well.
// Don't display a create-prompt for a value that's selected.
Expand Down Expand Up @@ -76,7 +76,11 @@ class CreatableSelect extends React.Component {
valueKey: this.valueKey
});

filteredOptions.unshift(this._createPlaceholderOption);
if (showNewOptionAtTop) {
filteredOptions.unshift(this._createPlaceholderOption);
} else {
filteredOptions.push(this._createPlaceholderOption);
}
}
}

Expand Down Expand Up @@ -251,7 +255,8 @@ CreatableSelect.defaultProps = {
menuRenderer: defaultMenuRenderer,
newOptionCreator,
promptTextCreator,
shouldKeyDownEventCreateNewOption
shouldKeyDownEventCreateNewOption,
showNewOptionAtTop: true
};

CreatableSelect.propTypes = {
Expand Down Expand Up @@ -299,6 +304,11 @@ CreatableSelect.propTypes = {

// Decides if a keyDown event (eg its `keyCode`) should result in the creation of a new option.
shouldKeyDownEventCreateNewOption: PropTypes.func,

// Where to show prompt/placeholder option text.
// true: new option prompt at top of list (default)
// false: new option prompt at bottom of list
showNewOptionAtTop: React.PropTypes.bool,
};


Expand Down
11 changes: 11 additions & 0 deletions test/Creatable-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,17 @@ describe('Creatable', () => {
expect(creatableNode.querySelector('.Select-create-option-placeholder'), 'to have text', Select.Creatable.promptTextCreator('foo'));
});

it('should add a placeholder "create..." prompt as last option when showNewOptionAtTop is false', () => {
createControl({
showNewOptionAtTop: false
});
const searchTerm = 'Th';
typeSearchText(searchTerm);
let nodes = creatableNode.querySelectorAll('.Select-option');
expect(nodes, 'to have length', 2); // [Three, Create "th"?]
expect(nodes[nodes.length-1], 'to have text', Select.Creatable.promptTextCreator(searchTerm));
});

it('should not show a "create..." prompt if current filter text is an exact match for an existing option', () => {
createControl({
isOptionUnique: () => false
Expand Down