diff --git a/examples/tags.html b/examples/tags.html new file mode 100644 index 000000000..b3a425249 --- /dev/null +++ b/examples/tags.html @@ -0,0 +1 @@ +placeholder \ No newline at end of file diff --git a/examples/tags.js b/examples/tags.js new file mode 100644 index 000000000..f6c7fc798 --- /dev/null +++ b/examples/tags.js @@ -0,0 +1,32 @@ +var React = require('react'); +var Select = require('rc-select'); +var Option = Select.Option; +require('./examples.css'); +require('rc-menu/assets/index.css'); +require('rc-select/assets/index.css'); +var children = []; +for (var i = 10; i < 36; i++) { + children.push(); +} + +function handleChange(value) { + console.log('selected ' + value); +} + +var style = '.rc-select-menu {height:200px;overflow:auto;}'; + +var c2 = ( +
+

multiple select(scroll the menu)

+
+ + +
+
+); + +React.render(c2, document.getElementById('__react-content')); diff --git a/lib/Select.js b/lib/Select.js index f922ebd49..1c5bc2ab5 100644 --- a/lib/Select.js +++ b/lib/Select.js @@ -11,6 +11,10 @@ var KeyCode = rcUtil.KeyCode; var Menu = require('rc-menu'); var MenuItem = Menu.Item; +function isMultipleOrTags(props){ + return props.multiple || props.tags; +} + function noop() { } @@ -95,7 +99,7 @@ class Select extends React.Component { this.setState({ open: open }, ()=> { - if (open || this.props.multiple || this.props.combobox) { + if (open || isMultipleOrTags(this.props) || this.props.combobox) { this.refs.input.getDOMNode().focus(); } else { this.refs.selection.getDOMNode().focus(); @@ -158,7 +162,7 @@ class Select extends React.Component { handleMenuSelect(key, item) { var value; - if (this.props.multiple) { + if (isMultipleOrTags(this.props)) { value = this.state.value.concat(); value.push(item.props.value); } else { @@ -168,7 +172,7 @@ class Select extends React.Component { } value = [item.props.value]; } - this.props.onChange(this.props.multiple ? value : value[0]); + this.props.onChange(isMultipleOrTags(this.props) ? value : value[0]); this.setState({ value: value, inputValue: '' @@ -207,7 +211,7 @@ class Select extends React.Component { value = this.state.value.filter((v)=> { return v !== value; }); - this.props.onChange(this.props.multiple ? value : value[0]); + this.props.onChange(isMultipleOrTags(this.props) ? value : value[0]); this.setState({ value: value }); @@ -216,7 +220,7 @@ class Select extends React.Component { handleClearSelection(e) { e.stopPropagation(); if (this.state.value.length) { - this.props.onChange(this.props.multiple ? [] : undefined); + this.props.onChange(isMultipleOrTags(this.props) ? [] : undefined); this.setState({ value: [], inputValue: '' @@ -228,7 +232,7 @@ class Select extends React.Component { renderMenu(children) { var props = this.props; var menuProps = {}; - if (props.multiple) { + if (isMultipleOrTags(props)) { menuProps.onDeselect = this.handleMenuDeselect; } var value = this.state.value; @@ -248,7 +252,7 @@ class Select extends React.Component { onSelect={this.handleMenuSelect} activeFirst={true} activeKey={activeKey} - multiple={props.multiple} + multiple={isMultipleOrTags(props)} focusable={false} {...menuProps} selectedKeys={selectedKeys} @@ -265,14 +269,14 @@ class Select extends React.Component { onClick={this.handleClearSelection}>×; var props = this.props; // single and not combobox, input is inside dropdown - if (!props.combobox && !props.multiple) { + if (!props.combobox && !isMultipleOrTags(props)) { return {value[0]} {allowClear ? clear : null} ; } var selectedValueNodes; - if (props.multiple) { + if (isMultipleOrTags(props)) { selectedValueNodes = value.map((v) => { return (
  • @@ -287,7 +291,7 @@ class Select extends React.Component { return ( ); @@ -317,7 +321,7 @@ class Select extends React.Component { render() { var props = this.props; - var multiple = props.multiple; + var multiple = isMultipleOrTags(this.props); var prefixCls = props.prefixCls; var input = ( @@ -331,7 +335,9 @@ class Select extends React.Component { var children = this._getFilterList(this.state.inputValue); if (!children.length) { - children = {props.notFoundContent}; + children = !this.props.tags ? + {props.notFoundContent} : + {this.state.inputValue}; } var ctrlNode = this.getTopControlNode(input); @@ -377,6 +383,7 @@ class Select extends React.Component { Select.propTypes = { multiple: React.PropTypes.bool, + tags: React.PropTypes.bool, onChange: React.PropTypes.func }; diff --git a/tests/Select.spec.js b/tests/Select.spec.js index a8def07ed..95ab4508f 100644 --- a/tests/Select.spec.js +++ b/tests/Select.spec.js @@ -119,6 +119,47 @@ describe('Select', function () { done(); }, 100); }); + + }); + + describe('when use option tags', function () { + var div; + + this.timeout(400000); + + beforeEach(function () { + div = document.createElement('div'); + div.tabIndex = 0; + document.body.appendChild(div); + instance = React.render( + , + div); + }); + + afterEach(function () { + React.unmountComponentAtNode(div); + }); + + it('should allow user input as tags', function (done) { + if (navigator.userAgent.indexOf(' Chrome') === -1) { + done(); + return; + } + + var node = React.findDOMNode(instance.refs.input); + React.addons.TestUtils.Simulate.keyDown( node, {key:"A"} ) + + setTimeout(function () { + React.addons.TestUtils.Simulate.keyDown( node, {key:"Enter"} ) + setTimeout(function () { + expect(instance.state.value).to.contain("A"); + }, 100); + done(); + }, 100); + }); }); });